Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411525 Posts in 69377 Topics- by 58431 Members - Latest Member: Bohdan_Zoshchenko

April 28, 2024, 04:45:44 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)The grumpy old programmer room
Pages: 1 ... 272 273 [274] 275 276 ... 295
Print
Author Topic: The grumpy old programmer room  (Read 738980 times)
Crimsontide
Level 5
*****


View Profile
« Reply #5460 on: September 11, 2017, 06:38:49 AM »

So I'm working on an aquarium controller for a home/DIY project and to play around with MCU's.  So I've been busy programming away with the Esp8266, and getting things done for the most part...

That said, I just got to rant.  The libraries for this thing, I know they are free, but what a mess.  Its like going back 30 years.  Macro's everywhere, build systems so convoluted they are 10x more complex than any of the code.  Constants defined in 4 different places for no apparent reason.  Documentation thats near impossible to find and wrong 1/2 the time when you can actually find it.  And debugging/working with it has made me really miss my VS IDE and its integrated debugger.

I've also come across probably the most bizarre error I've seen in a very long time.  In trying to create just a simple spin-loop delay function, I've created what I though to be two identical pieces of code...

Code:
ICACHE_RAM_ATTR uint32_t CounterTest(uint32_t counter) {

  uint32_t start, end;

  __asm__ volatile (
    "rsr.ccount %[r_start];"
    "loop_%=:"
    "addi.n %[r_counter], %[r_counter], -1;"
    "bnez.n %[r_counter], loop_%=;"
    "rsr.ccount %[r_end];"
    : [r_start] "=r" (start), [r_end] "=r" (end), [r_counter] "+r" (counter)
    : // no inputs
    );

  return end - start;
  }

template<uint32_t count> uint32_t CounterTest2() ICACHE_RAM_ATTR;

template<uint32_t count> uint32_t CounterTest2() {

  uint32_t counter = count;
  uint32_t start, end;

  __asm__ volatile (
    "rsr.ccount %[r_start];"
    "loop_%=:"
    "addi.n %[r_counter], %[r_counter], -1;"
    "bnez.n %[r_counter], loop_%=;"
    "rsr.ccount %[r_end];"
    : [r_start] "=r" (start), [r_end] "=r" (end), [r_counter] "+r" (counter)
    : // no inputs
    );

  return end - start;
  }

void AsmTest() {
  static bool run_once = false;
  if (run_once) return;
  else run_once = true;
 
  uint32_t count0 = CounterTest(1);
  uint32_t count1 = CounterTest(10);
  uint32_t count2 = CounterTest(100);
  uint32_t count3 = CounterTest(1000);

  uint32_t count4 = CounterTest2<1>();
  uint32_t count5 = CounterTest2<10>();
  uint32_t count6 = CounterTest2<100>();
  uint32_t count7 = CounterTest2<1000>();
 
  lcd.Clear();
 
  ReadyLn(lcd, 0);
  Utility::Print(lcd, count0);
  Utility::Print(lcd, " / ");
  Utility::Print(lcd, count4);
  Utility::Print(lcd, " / ");
  Utility::Print(lcd, 1);

  ReadyLn(lcd, 1);
  Utility::Print(lcd, count1);
  Utility::Print(lcd, " / ");
  Utility::Print(lcd, count5);
  Utility::Print(lcd, " / "); 
  Utility::Print(lcd, 10);

  ReadyLn(lcd, 2);
  Utility::Print(lcd, count2);
  Utility::Print(lcd, " / ");
  Utility::Print(lcd, count6);
  Utility::Print(lcd, " / ");
  Utility::Print(lcd, 100);

  ReadyLn(lcd, 3);
  Utility::Print(lcd, count3);
  Utility::Print(lcd, " / ");
  Utility::Print(lcd, count7);
  Utility::Print(lcd, " / "); 
  Utility::Print(lcd, 1000);
  }

Otherwise identical functions that should just spin loop... And yet they give different results.  Its not crucial for anything, I was just playing around and trying stuff out at the low level; but I'd love to know why they give different results...  And if anyone has played with MCUs, is there any way to embed template constants into inline assembly?  Being able to encode things like pin definitions directly into assembly could really yield some interesting possibilities.
Logged
Photon
Level 4
****


View Profile
« Reply #5461 on: September 11, 2017, 10:59:08 AM »

Anyone ever feel like the more they code, the slower they get? Tongue

It kinda feels like I'm starting to overcome the Dunning-Kruger effect but my recognition of that is causing lots of apprehensiveness about my own code.
Logged
gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #5462 on: September 11, 2017, 12:19:04 PM »

One thing that made me mad is when I need to pause to find names for variables or functions:
Too often I code and everything seems like it should be named:

Code:
class name{
    var name;
    name name;

    void Name(name)
    {
        return name.name;
    }

}

It takes age to express the nuances of the difference, finding synonym, adjectives, prefix or suffix. It's a distraction from the main challenge Sad Especially in the case you have a noun that double as a verb.  Lips Sealed
Logged

qMopey
Level 6
*


View Profile WWW
« Reply #5463 on: September 11, 2017, 12:37:04 PM »

One thing that made me mad is when I need to pause to find names for variables or functions:
Too often I code and everything seems like it should be named:

Code:
class name{
    var name;
    name name;

    void Name(name)
    {
        return name.name;
    }

}

It takes age to express the nuances of the difference, finding synonym, adjectives, prefix or suffix. It's a distraction from the main challenge Sad Especially in the case you have a noun that double as a verb.  Lips Sealed

That's actually a sign of over-engineering for the task at hand. The problem you're solving probably does not need that level of expression. Sometimes a free function named as a verb, along with a few parameters with potentially abstract names, is all that is needed.
Logged
gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #5464 on: September 11, 2017, 12:46:06 PM »

Certainly, the expression above is comically exaggerated (and simplified too), more often it's name.name that happen (and I see it in other people's code too) but there is something to say when over engineering takes less mental cost that finding the obvious solution right away. And that's to keep the code readable and self commented, because reading code is a mess to me, even after 20years.


Logged

RogerBidon
Level 0
**



View Profile
« Reply #5465 on: September 11, 2017, 02:01:56 PM »

Just got the day to understand a little trivial oddity... I only found three ways of proving that there is no problem, and ultimately had to apply an uggly hack to hide the oddity. Another lost day.
Logged
Garthy
Level 9
****


Quack, verily


View Profile WWW
« Reply #5466 on: September 11, 2017, 04:02:43 PM »


So I'm working on an aquarium controller for a home/DIY project and to play around with MCU's. ... That said, I just got to rant.  The libraries for this thing ...

Welcome to hell! :D

By way of explanation of your situation. The people who create microcontrollers are brilliant, brilliant electrical engineers, who happen to be terrible software developers, who delegate to inexperienced interns in a critically underfunded area to write the software libraries.

Be thankful you aren't doing development on STM32 ARM code, which comes with quite possibly the worst libraries in the industry.

Microcontroller development is fun, and comes with a completely different set of challenges from normal software development. This is what I've been working on:

http://www.entropicsoftware.com/aie/sat/overview.html

And if anyone has played with MCUs, is there any way to embed template constants into inline assembly?  Being able to encode things like pin definitions directly into assembly could really yield some interesting possibilities.

Could stringification (https://en.wikipedia.org/wiki/C_preprocessor#Token_stringification) be used? I haven't tried it with template constants personally. You might need to get creative. It might be a useless suggestion, but I'd start there. EDIT: As feared my blind guess was useless. This might get you a bit closer: https://stackoverflow.com/questions/1488186/stringifying-template-arguments

I usually fall back to scripting to generate code when the problem reaches a sufficient complexity. Basically spit out the code into a generated file that you #include in. It helps if you need to get more creative with the code than macros/templating allow. Inline assembly support in gcc is (was?) weak, so my threshold for just shifting it to an external generator is pretty low in this case.
« Last Edit: September 11, 2017, 05:08:14 PM by Garthy » Logged
ProgramGamer
Administrator
Level 10
******


aka Mireille


View Profile
« Reply #5467 on: September 14, 2017, 12:27:56 PM »

C++ is a strongly typed language that has various features that utilise type deduction for convenience. It also has a special syntax for aliasing existing types to new type names. These newly defined type names don't work with type deduction when multiple aliases refer to the same basic data type.

This is an approximation of my use case btw:

Code:
typedef int defenseStat
typedef int attackStat

std::ostream& operator<<(std::ostream& stream, const defenseStat& defense)
{
    return stream << "Defense: " << defense;
}

std::ostream& operator<<(std::ostream& stream, const attackStat& attack)
{
    return stream << "Attack: " << attack;
}

attackStat attack = 3;
defenseState defense = 5;

std::cout << attack << std::endl << defense << std::endl;


I know this wouldn't work because I'm trying to redefine the streaming operator for int, but in my actual use case I was using a custom std::array type that I was trying to typedef twice.

This paper explains in more detail what I would want: Name_template
« Last Edit: September 14, 2017, 12:45:33 PM by ProgramGamer » Logged

oahda
Level 10
*****



View Profile
« Reply #5468 on: September 14, 2017, 09:33:01 PM »

Yeah, they aren't actually separate types but just aliases for the same type, so that's why it doesn't work. Their type is still int. You can go about it by creating either a strongly typed enum (without any values) or a struct, but either way you're going to have to implement all the operators yourself if you want to be able to use it like an int. Probably better to just create logAttack() functions and such.
Logged

Ordnas
Level 10
*****



View Profile WWW
« Reply #5469 on: September 14, 2017, 11:55:30 PM »

C++ is a strongly typed language that has various features that utilise type deduction for convenience. It also has a special syntax for aliasing existing types to new type names. These newly defined type names don't work with type deduction when multiple aliases refer to the same basic data type.

This is an approximation of my use case btw:

Code:
typedef int defenseStat
typedef int attackStat

std::ostream& operator<<(std::ostream& stream, const defenseStat& defense)
{
    return stream << "Defense: " << defense;
}

std::ostream& operator<<(std::ostream& stream, const attackStat& attack)
{
    return stream << "Attack: " << attack;
}

attackStat attack = 3;
defenseState defense = 5;

std::cout << attack << std::endl << defense << std::endl;


I know this wouldn't work because I'm trying to redefine the streaming operator for int, but in my actual use case I was using a custom std::array type that I was trying to typedef twice.

This paper explains in more detail what I would want: Name_template


What about to avoid using typedef as much as possible? If you work in a team enviroment, there could be the risk that a programmer can misunderstand a large structure for a simple value. For function prototype declaration could be ok instead.
Logged

Games:

ProgramGamer
Administrator
Level 10
******


aka Mireille


View Profile
« Reply #5470 on: September 15, 2017, 02:35:01 AM »

But, as I've said, I'm not actually using it to alias ints, I'm using it to alias a specific templated std::array.
Logged

oahda
Level 10
*****



View Profile
« Reply #5471 on: September 15, 2017, 05:53:59 AM »

What's the actual non-pseudocode? o:
Logged

ProgramGamer
Administrator
Level 10
******


aka Mireille


View Profile
« Reply #5472 on: September 15, 2017, 06:22:29 AM »

I was declaring two typedefs of a std::array<bool, 9> and overloading the streaming operators with the typedefs in the hopes that output formatting would be automatic.
Logged

oahda
Level 10
*****



View Profile
« Reply #5473 on: September 15, 2017, 09:21:38 AM »

Ah, yes. Yeah, as long as the aliases refer to the same underlying type, they really are the same. I'm guessing you got an "already defined" error for the second overload?
Logged

ProgramGamer
Administrator
Level 10
******


aka Mireille


View Profile
« Reply #5474 on: September 15, 2017, 09:52:35 AM »

Yeap. For a strongly typed language, C++ doesn't really make optimal use of its features.

I managed to find a workaround, but it's not perfect. I basically just made empty children of the arrays I wanted to have a typedef for.
Logged

oahda
Level 10
*****



View Profile
« Reply #5475 on: September 15, 2017, 10:19:32 AM »

Yeah, it would be nice if you could do it in one line without having to implement all the operators and such yourself.

I guess you can always create a monster macro… Shrug
Logged

ProgramGamer
Administrator
Level 10
******


aka Mireille


View Profile
« Reply #5476 on: September 15, 2017, 12:18:58 PM »

I, uh, tried to do that.

It didn't work because of how macros function. You basically can't pass a type to a macro, so it's impossible to produce a "strong_typedef" macro.
Logged

Photon
Level 4
****


View Profile
« Reply #5477 on: September 15, 2017, 12:30:40 PM »

One thing that made me mad is when I need to pause to find names for variables or functions:
Too often I code and everything seems like it should be named:

Code:
class name{
    var name;
    name name;

    void Name(name)
    {
        return name.name;
    }

}

It takes age to express the nuances of the difference, finding synonym, adjectives, prefix or suffix. It's a distraction from the main challenge Sad Especially in the case you have a noun that double as a verb.  Lips Sealed
This is actually something I found happening with my entity component systems. I'd make something like a "TextFieldComponent" and then be like "So what do I name the actual text variable?" I'd end up with things like "text_comp.text" as a reference. Now when that conflict arises, I typically do something like just calling the main variable "data."

That being said, I'm beginning to feel like entity component systems are really prone to over-engineering period.
Logged
qMopey
Level 6
*


View Profile WWW
« Reply #5478 on: September 15, 2017, 12:47:34 PM »

That being said, I'm beginning to feel like entity component systems are really prone to over-engineering period.

Yep. I work with an entity component system in day job, and so far would say it's over-engineered. It seems to be unavoidable.
Logged
InfiniteStateMachine
Level 10
*****



View Profile
« Reply #5479 on: September 15, 2017, 01:24:16 PM »

that term is starting to lose all meaning to me
Logged

Pages: 1 ... 272 273 [274] 275 276 ... 295
Print
Jump to:  

Theme orange-lt created by panic