Author Topic: C++ for the Embedded Programmer  (Read 26829 times)

0 Members and 1 Guest are viewing this topic.

Offline thm_w

  • Super Contributor
  • ***
  • Posts: 6272
  • Country: ca
  • Non-expert
Re: C++ for the Embedded Programmer
« Reply #25 on: March 06, 2018, 11:44:11 pm »
Why are people fixated on screen grabbing desktops running resolutions like 1920*1080 to show code ?

Most editors have the ability to scale the text easily, so he just needs to remember to do that in the future (think it was discussed in the YT comments).
Profile -> Modify profile -> Look and Layout ->  Don't show users' signatures
 

Offline NexusKoolaid

  • Contributor
  • Posts: 23
  • Country: us
Re: C++ for the Embedded Programmer
« Reply #26 on: March 07, 2018, 12:01:40 am »
All those pointers to pointers to pointers... consume a lot of memory and CPU time.
Memory and time for vtables - negligible in most circumstances.  RTTI and dynamic_cast on the other hand...
 

Offline Fungus

  • Super Contributor
  • ***
  • Posts: 16560
  • Country: 00
Re: C++ for the Embedded Programmer
« Reply #27 on: March 07, 2018, 09:23:18 am »
All those pointers to pointers to pointers... consume a lot of memory and CPU time.

There's only one vtable in memory for each type of object. You can have a billion objects in RAM and they all point to the same vtable. Result: Maximum possible overhead per object is one pointer (and that's only if your object has virtual functions, otherwise it's zero).

The reason "why it takes 4 GB of DRAM to run Firefox" isn't C++. C++ is one of the leanest, meanest programming languages ever*. The reason it takes 4GB is because the old C++ function called "drawAButton()" has now been replaced by a Python interpreter which reads a script file then translates it to a meta language to be interpreted by some rendering API which is a wrapper for a framework that uses a Javascript core running in a sandbox to draw the same square with a border around it as before.

This design makes everything more customizable so people can use "themes" (just edit the script!)

In practice: Nobody will ever create themes because every single Firefox update will change something that breaks them. All theme creators eventually get pissed off and stop trying to keep up.
« Last Edit: March 07, 2018, 09:27:59 am by Fungus »
 
The following users thanked this post: Frank

Offline GeorgeOfTheJungle

  • Super Contributor
  • ***
  • !
  • Posts: 2699
  • Country: tr
Re: C++ for the Embedded Programmer
« Reply #28 on: March 07, 2018, 12:15:19 pm »
One of the first things I typically do is add braces to all conditionals.  If I want to stop on the Nth iteration of a loop for N large, I'll put in:

if( i  == N ){
    printf( "fubar" );
}

and set a breakpoint on the printf.

Without the braces:

Code: [Select]

if (i == N)
    printf("fubar");


You can't set the breakpoint?
« Last Edit: March 08, 2018, 07:00:13 am by GeorgeOfTheJungle »
The further a society drifts from truth, the more it will hate those who speak it.
 

Offline Fungus

  • Super Contributor
  • ***
  • Posts: 16560
  • Country: 00
Re: C++ for the Embedded Programmer
« Reply #29 on: March 07, 2018, 01:32:45 pm »
One of the first things I typically do is add braces to all Without the braces:

Code: [Select]
if (i  == N)
    printf( "fubar" );

You can't set the breakpoint?

That made no sense to me either but it's irrelevant.

It's nothing to do with "C++" or "programming style", at most it's just some IDE problem.

« Last Edit: March 07, 2018, 02:15:26 pm by Fungus »
 

Offline rhb

  • Super Contributor
  • ***
  • Posts: 3476
  • Country: us
Re: C++ for the Embedded Programmer
« Reply #30 on: March 07, 2018, 02:33:47 pm »
Don't take my word for it, try it.  Without the braces it's a single statement that begins with the "if" and ends with the ";".  The compiler and debugger don't care about the formatting.   Same problem with "d = a ? b : c; "   

The behavior is a necessary consequence of parsing the source code.  Unless you change the grammar it *has* to be that way.  The code generated by the compiler will be the same in all 3 cases for equivalent conditionals.

Language features that save typing generally incur huge  debugging costs.  Implicit typing in FORTRAN is the most pernicious of the "save a few keystrokes" features.  I won't even attempt to compile an old FORTRAN code until I've inserted "IMPLICIT NONE".  I had an automated script that generated the declarations from the compiler error messages.  So I could add declarations to a 100,000+ line program in an hour or so.  I also put all named COMMONs in an include file and run the mess through the C preprocessor.  Just those two steps have caught and fixed more bugs than I can count.

If you thoroughly understand the C standard, there is nothing that C++ offers that you cannot do in C.   C++ just automates a bunch of stuff to save keystrokes.  But TANSTAFL.  The price is paid in core and cycles.
 

Offline AlfBaz

  • Super Contributor
  • ***
  • Posts: 2183
  • Country: au
Re: C++ for the Embedded Programmer
« Reply #31 on: March 07, 2018, 02:38:50 pm »
Personally I think this is mistitled. C doesn't mean ST horrible HAL, so it is not fair to put equality between a poorly written library and a language.
Yep
GPIO_SetBits(BLINK_GPIOz(BLINK_PORT_NUMBER), BLINK_PIN_MASK(BLINK_PIN_NUMBER));
vs
GPIOx->BSRRL |= GPIO_Pin_x;
 >:D
 

Offline alexanderbrevig

  • Frequent Contributor
  • **
  • Posts: 700
  • Country: no
  • Musician, developer and EE hobbyist
    • alexanderbrevig.com
Re: C++ for the Embedded Programmer
« Reply #32 on: March 07, 2018, 03:41:17 pm »
If you thoroughly understand the C standard, there is nothing that C++ offers that you cannot do in C.   C++ just automates a bunch of stuff to save keystrokes.  But TANSTAFL.  The price is paid in core and cycles.

If you thoroughly understand the C++17 standard then you know that the above statement is false. Even at compile time.

The C++ compiler knows much more about the code and can do a lot more optimizations than a C compiler can. In C you can of course write optimized code, but you can do the same with C++.
A real challenge would be to find some C program that can't be written at least as efficiently with C++
 

Offline NexusKoolaid

  • Contributor
  • Posts: 23
  • Country: us
Re: C++ for the Embedded Programmer
« Reply #33 on: March 07, 2018, 03:50:26 pm »
Don't take my word for it, try it.  Without the braces it's a single statement that begins with the "if" and ends with the ";".  The compiler and debugger don't care about the formatting.   Same problem with "d = a ? b : c; "

Code: [Select]
int N = 5;
for (int i = 0; i < 10; i++)
if (i == N)
printf("Muffins");

A breakpoint on the printf statement will be hit exactly once, when I = 5.  If you get different results I suggest you update your tool set.  That said, some compilers will have a problem when the if statement appears on a single line, but this has nothing to do with the presence or absence of curly braces. 

Quote
The behavior is a necessary consequence of parsing the source code.  Unless you change the grammar it *has* to be that way.  The code generated by the compiler will be the same in all 3 cases for equivalent conditionals.

You seem to be mixing apples and oranges here.  Of course the code generated by the compiler will be the same, but the issue that was raised involved the placement of breakpoints.  If you review c/c++ grammar you will see that the compiler can identify statements whether they are expressed alone or within a compound statement.
« Last Edit: March 07, 2018, 05:21:57 pm by NexusKoolaid »
 

Offline GeorgeOfTheJungle

  • Super Contributor
  • ***
  • !
  • Posts: 2699
  • Country: tr
Re: C++ for the Embedded Programmer
« Reply #34 on: March 07, 2018, 04:08:40 pm »
And in javascript (also a C-like syntax language) you can also set a breakpoint like that:

« Last Edit: March 07, 2018, 04:33:59 pm by GeorgeOfTheJungle »
The further a society drifts from truth, the more it will hate those who speak it.
 

Offline Fungus

  • Super Contributor
  • ***
  • Posts: 16560
  • Country: 00
Re: C++ for the Embedded Programmer
« Reply #35 on: March 07, 2018, 04:45:50 pm »
If you thoroughly understand the C standard, there is nothing that C++ offers that you cannot do in C.

If you understand assembly language there is nothing that C offers that you cannot do in assembler.


C++ just automates a bunch of stuff to save keystrokes.

C compilers just automate a bunch of stuff to save keystrokes.

 
The following users thanked this post: Jeroen3, Frank, NexusKoolaid

Offline rhb

  • Super Contributor
  • ***
  • Posts: 3476
  • Country: us
Re: C++ for the Embedded Programmer
« Reply #36 on: March 08, 2018, 12:17:35 am »
Don't take my word for it, try it.  Without the braces it's a single statement that begins with the "if" and ends with the ";".  The compiler and debugger don't care about the formatting.   Same problem with "d = a ? b : c; "

Code: [Select]
int N = 5;
for (int i = 0; i < 10; i++)
if (i == N)
printf("Muffins");

A breakpoint on the printf statement will be hit exactly once, when I = 5.  If you get different results I suggest you update your tool set.  That said, some compilers will have a problem when the if statement appears on a single line, but this has nothing to do with the presence or absence of curly braces. 

Quote
The behavior is a necessary consequence of parsing the source code.  Unless you change the grammar it *has* to be that way.  The code generated by the compiler will be the same in all 3 cases for equivalent conditionals.

You seem to be mixing apples and oranges here.  Of course the code generated by the compiler will be the same, but the issue that was raised involved the placement of breakpoints.  If you review c/c++ grammar you will see that the compiler can identify statements whether they are expressed alone or within a compound statement.

What compiler and debugger on what OS?  I've used every major Unix vendor compiler plus quite a few more.  It would certainly be nice if you can hit that breakpoint, but I've never seen anything that does it..
 

Offline AlfBaz

  • Super Contributor
  • ***
  • Posts: 2183
  • Country: au
Re: C++ for the Embedded Programmer
« Reply #37 on: March 08, 2018, 12:32:45 am »
What compiler and debugger on what OS?  I've used every major Unix vendor compiler plus quite a few more.  It would certainly be nice if you can hit that breakpoint, but I've never seen anything that does it..
arm-none-eabi-gcc/gdb here on eclipse, no problems
 
The following users thanked this post: hans

Offline AlfBaz

  • Super Contributor
  • ***
  • Posts: 2183
  • Country: au
Re: C++ for the Embedded Programmer
« Reply #38 on: March 08, 2018, 12:35:51 am »
Could it be you are trying to debug code with optimisation or at least no -g option? Break points are harder to hit in this situation
 

Online Brumby

  • Supporter
  • ****
  • Posts: 12287
  • Country: au
Re: C++ for the Embedded Programmer
« Reply #39 on: March 08, 2018, 01:02:08 am »
If you thoroughly understand the C standard, there is nothing that C++ offers that you cannot do in C.

If you understand assembly language there is nothing that C offers that you cannot do in assembler.


C++ just automates a bunch of stuff to save keystrokes.

C compilers just automate a bunch of stuff to save keystrokes.

Dang.  You beat me to it.
 

Offline rhb

  • Super Contributor
  • ***
  • Posts: 3476
  • Country: us
Re: C++ for the Embedded Programmer
« Reply #40 on: March 08, 2018, 01:06:55 am »
I'm about to turn 65 and have debugged over 2.5 million lines of other people's code.  Most of it very complex scientific and DSP stuff.

I'm about to bring up a BeagleBoard X15 so I shall be very interested ti test the assertion.  It certainly would be convenient.

The price for automating assembly with C is a lot lower the the cost of restricting scope with C++.  I happen to remember doing real work on machines with 4 MB of memory. 
 

Offline hans

  • Super Contributor
  • ***
  • Posts: 1626
  • Country: nl
Re: C++ for the Embedded Programmer
« Reply #41 on: March 08, 2018, 08:39:31 am »
I think rhb has a fair point.

Sure C++ offers a bunch of tools to manage complexity, but there are a lot of undesirable constructs that you shouldn't touch on embedded (like exceptions, new operator, etc.), and some abstractions that can generate a huge bunch of code with a single value assignment. Additionally you may find that C++ can fold a whole bunch of expressions in 1 part of your project because all the const and static assignments were setup nicely. But in another setting it may not.
For latter C is way more predictable in how it compiles to code. Function callbacks are simpler in C IMHO.

Additionally, if you turn the C++ optimizer off you may find that code can literally run a dozen times slower. Ofcourse; depends on the complexity of the code and layers of abstraction built. But I think it's atypical  that C++ projects will tend to write more abstractions.

Binary images explode in size, because all simple 'layered' functions are compiled to separately. Then if you do turn on the optimizer to g (inlining a lot of these statements), you may find you still cannot set breakpoints if you're calling that method from 5 different places and your device only has 4 breakpoints.

Now personally I think a lot of these issues can easily be alleviated with unit testing on a workstation, which is a mindful thing to do anyway, and I think the added abstractions and nice "packaging" of agnostic device drivers is worth investing some extra time and optimizing.
 

Offline Fungus

  • Super Contributor
  • ***
  • Posts: 16560
  • Country: 00
Re: C++ for the Embedded Programmer
« Reply #42 on: March 08, 2018, 12:18:21 pm »
The price for automating assembly with C is a lot lower the the cost of restricting scope with C++. 

It's strange to think that most "C compilers" these days are really just C++ compilers with a few options turned off.

You'd think they'd re-use the same code generator and optimizer for both languages instead of having two - one for C++ and a much better one for C.

Oh, wait...

I happen to remember doing real work on machines with 4 MB of memory.

Oh, you youngsters. You don't know you're born!

PS: Arduinos have 32kb program memory and 2kb of RAM. They're mostly programmed in C++ using a C++ compiler. Go figure.
« Last Edit: March 08, 2018, 12:34:52 pm by Fungus »
 
The following users thanked this post: janoc

Offline Fungus

  • Super Contributor
  • ***
  • Posts: 16560
  • Country: 00
Re: C++ for the Embedded Programmer
« Reply #43 on: March 08, 2018, 12:33:34 pm »
I think rhb has a fair point.

Sure C++ offers a bunch of tools to manage complexity, but there are a lot of undesirable constructs that you shouldn't touch on embedded (like exceptions, new operator, etc.), and some abstractions that can generate a huge bunch of code with a single value assignment.

One of the mantras of C++ design was "you don't pay for what you don't use".

If you're not using polymorphism or exceptions then C++ will use no more memory and generate no more code than C.

And ... even without those things you still gain an awful lot: eg. Objects make code a lot cleaner and easier to re-use.

Explanation: Any language which just dumps everything into a single global namespace is just asking for trouble when you try to copy code from it into another project. C++ puts related variables and functions into little mini-namespaces (aka"classes") which are much less likely to cause problems.

 
The following users thanked this post: thm_w, alexanderbrevig

Offline rhb

  • Super Contributor
  • ***
  • Posts: 3476
  • Country: us
Re: C++ for the Embedded Programmer
« Reply #44 on: March 08, 2018, 01:50:36 pm »

One of the mantras of C++ design was "you don't pay for what you don't use".

If you're not using polymorphism or exceptions then C++ will use no more memory and generate no more code than C.

And ... even without those things you still gain an awful lot: eg. Objects make code a lot cleaner and easier to re-use.


If you're not using classes, it's a dialect of C, not C++.  Once you start using classes, every object drags with it a table of pointers to all the methods, public and private.  If you inherit from a base class, you have a table of pointers to a table of pointers in the base class.  I  watched a bunch of UI programmers merrily design objects with 4 & 5 antecedent classes even though there was no need for it. "Design Patterns" had just come out and they were hot to be using the latest jargon.  Aside from the increased memory footprint, that's a lot of constructors which have to be run to instantiate an object.

I warned them at the start of the project (I was strictly doing scientific codes) to keep an eye on their linker dependencies by way of a page from "Large-Scale C++ Program Design" by John Lakos posted on my door. This was ignored until the compile times became intolerable and they had to stop work while they refactored the mess they had made.  I was quite startled when one of them pulled a copy of that page out of his desk.  He *had* paid attention.

I've seen a good bit of "C++" which was actually just C with C++ semantics.  In that case the compiler may or may not generate the same code.  It depends upon whether the code touches an edge case where the two languages differ.

This is the reason for the staggering code bloat.  The Vivado FPGA suite from Xilinx is a 20 GB download!  Firefox has a runtime  memory footprint of  over a GB.

A well designed and documented  library in any language is easy to reuse.  C++ requires that you include all the antecedent libraries even if the particular object you are using doesn't reference them.  An old FORTRAN code has the minimum possible dependencies as is also the case for assembly and C.

In case it's not obvious, I am what Fred Brooks described as a language lawyer.  Not only will I tell you that section 8.3.5 says that upon return from a function or subroutine named common may be undefined, I'll also explain that that behavior was included to allow FORTRAN 77 to run on the Burroughs 5000 which was the first stack based machine.  It also was a tagged architecture machine.  Every word in memory had a a set of bits that recorded the type of the value stored at that location.  I'm not aware of any other hardware that implemented that feature though I've read a great many expositions of the virtues of a tagged architecture.
 

Offline Fungus

  • Super Contributor
  • ***
  • Posts: 16560
  • Country: 00
Re: C++ for the Embedded Programmer
« Reply #45 on: March 08, 2018, 03:19:12 pm »
If you're not using polymorphism or exceptions then C++ will use no more memory and generate no more code than C.

And ... even without those things you still gain an awful lot: eg. Objects make code a lot cleaner and easier to re-use.

If you're not using classes, it's a dialect of C, not C++.

No True Scotsman...?


I  watched a bunch of UI programmers merrily design objects with 4 & 5 antecedent classes even though there was no need for it. "Design Patterns" had just come out and they were hot to be using the latest jargon.  Aside from the increased memory footprint, that's a lot of constructors which have to be run to instantiate an object.

I warned them at the start of the project (I was strictly doing scientific codes) to keep an eye on their linker dependencies by way of a page from "Large-Scale C++ Program Design" by John Lakos posted on my door. This was ignored until the compile times became intolerable and they had to stop work while they refactored the mess they had made.  I was quite startled when one of them pulled a copy of that page out of his desk.  He *had* paid attention.

This is the reason for the staggering code bloat.

Untrained programmers?

They could do that in any language. If they weren't doing it in C++ they'd be doing it in C# or whatever the language-du-jour is.

Writing something like UI code without polymorphic inheritance is going to be very unproductive. Just teach them to do C++ properly.

Firefox has a runtime  memory footprint of  over a GB.

As noted in a previous post: That's not because of C++.
« Last Edit: March 08, 2018, 04:53:37 pm by Fungus »
 
The following users thanked this post: thm_w

Offline IanMacdonald

  • Frequent Contributor
  • **
  • Posts: 943
  • Country: gb
    • IWR Consultancy
Re: C++ for the Embedded Programmer
« Reply #46 on: March 18, 2018, 01:54:18 pm »
Speaking generally (not just for C) the main advantage of OOP is in larger projects where coders are assigned to develop and manage subsections of the code. It allows them to create private functions without having to consider the possibility of namespace clashes with other coders' work.

I just don't see why you would want to use OO code for a single-coder project though. You're just making things far harder for yourself, for no good reason. If you can't keep track of your naming conventions, then you need to rethink your working practices because you are writing poor quality code. Using OOP will not change that basic situation. Although, it may act as a gaffertape fix.
 

Offline Fungus

  • Super Contributor
  • ***
  • Posts: 16560
  • Country: 00
Re: C++ for the Embedded Programmer
« Reply #47 on: March 19, 2018, 07:57:23 am »
Speaking generally (not just for C) the main advantage of OOP is in larger projects where coders are assigned to develop and manage subsections of the code. It allows them to create private functions without having to consider the possibility of namespace clashes with other coders' work.

I don't know if it's the main advantage but I know that the way classes take function names out of the global namespace is something the C diehards usually overlook, and it's a big win when you're writing large software, yes.

I just don't see why you would want to use OO code for a single-coder project though. You're just making things far harder for yourself, for no good reason.

a) Why is it any harder?  :-//

b) Associating code with data is often good even on tiny projects. eg. How would you write a traffic light controller that had to control four traffic lights without using objects?
 
The following users thanked this post: thm_w

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26751
  • Country: nl
    • NCT Developments
Re: C++ for the Embedded Programmer
« Reply #48 on: March 19, 2018, 09:13:44 am »
Speaking generally (not just for C) the main advantage of OOP is in larger projects where coders are assigned to develop and manage subsections of the code. It allows them to create private functions without having to consider the possibility of namespace clashes with other coders' work.

I just don't see why you would want to use OO code for a single-coder project though. You're just making things far harder for yourself, for no good reason. If you can't keep track of your naming conventions, then you need to rethink your working practices because you are writing poor quality code. Using OOP will not change that basic situation. Although, it may act as a gaffertape fix.
IMHO C++ is more than being able to use OO and you can code OO style in regular C as well. The big advantage of C++ is that you can avoid using pointers to a large extend and thus make code more reliable.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline rhb

  • Super Contributor
  • ***
  • Posts: 3476
  • Country: us
Re: C++ for the Embedded Programmer
« Reply #49 on: March 19, 2018, 01:17:44 pm »
Careful use of the C scoping rules neatly solves any namespace issues.  People *should* do that as a matter of course, but they don't.  Which is sad as all it requires is putting "static" in front of the global variables in a file and *never* using global variables unless *every* function needs them.  I've placed file scope variables just before the functions that needed them in some instances so that only those functions saw them.

I once wrote a parser in C which had a large conditional with many branches.  After I wrote it I realized that every function called from that structure had the same four arguments except for  two which had a 5th.  To make this obvious I made the 4 arguments global with file scope so that the two functions with an extra argument were obvious to whomever had to read the code later.

Pointers are not a problem if you are careful.  I've certainly fixed a *lot* of null pointer problems. but I can't recall any I made.  But my standard style includes a lot of:

if( !ptr ){
   // report null pointer and exit
}else{
   // get the job done
}

I once had an assignment to write a string substitution routine.  Given a string "old" substitute string "new". This was given to me because I had all my scientific routines done and they were trying to keep me busy.   I wrote it twice, once in C and once in C++.  The C++ version was 3 times as long as the C version to do the same thing.  I don't recall which the project used.  I'd guess the C++ version, but that's just a guess.

At about this time ('97-98) Les Hatton published a paper in the ACM journal discussing the statistics of several years maintenance on the static code analyzers his company sold.  The C analyzer was written in C and the C++ analyzer was written in C++.  The programming staff were analyzing C and C++ code for errors, so they were quite expert in both languages out of necessity.  The mean time to fix a bug on the C++ analyzer was significantly longer than the C analyzer.  Les later wrote a book, "Safer C".
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf