Hi, C++ is a language designed to be used with optimising compilers. Turning off optimisations cripples it - either you end up with so absurdly poor object code that you massively change the timing, and therefore behaviour, of your embedded system, or you have to limit yourself drastically in the kind of C++ you write. With the templates I have used for IO pin control (on a different target), unoptimised code can mean hundreds of instructions for simple port access - using -O1 gives the expected two or three instructions.
It is extremely rare that I find -O0 useful for any purpose. -O1 is the lowest I use, when doing complex debugging (as it avoids many of the code re-organisations of the higher levels I normally use). Assembly level debugging in particular is impossible with -O0 as you can't see what is going on for all the register and stack movements. (This applies equally to C and C++.) A lot of C++ code makes heavy use of functions that "disappear" - code that manipulates types rather than values, which are very useful to the aim of having the compiler help check the correctness of code but which you do not want as object-code functions. A lot of C++ has functions that have no name as such, or where the same source code produces multiple object code functions (generated from templates, lambdas, etc.) that are difficult when you want to put breakpoints. It is not impossible, but it can be less convenient - and sometimes you need to add artificial points (setting volatile variables, adding "no_inline" attributes, etc.) to help. (This applies to C too, but more so to C++.) When optimising, all bets are /not/ off. It is often entirely possible to know roughly how the compiler will generate code for optimised C or C++. On the other hand, it is often hard to tell what code will be generated for some code whether it is C or C++, optimised or not. This depends very much on the code in question, not the programming language. People who use C "because they know exactly what code the compiler produces" and think there is a one-to-one correspondence between C source and object code are simply wrong. If they need such a correspondence between source and object code, assembly is the only way to go. C++ gives more scope for distancing between the source and the object code, but does not change the principles. David On 12/04/2021 02:30, Trampas Stern wrote: > David, > > On the real cost of C++ I do not see the problems with debugging you > do. That is when I debug code I turn optimizations off, as such I can > debug C++ just like C. Now with compiler optimizations on all bets are > off as to what the compiler does. At this point you have to have near > complete trust the compiler is doing the right thing. > > If you do not trust the compiler to do the right thing, you are using > the wrong compiler. > > Trampas > > On Sun, Apr 11, 2021 at 8:10 AM David Brown <david.br...@hesbynett.no > <mailto:david.br...@hesbynett.no>> wrote: > > Well, if you want a flame war, then let me chime in - you are wrong, > Trampas is right. > > You are /wrong/ to suggest that "commercial embedded systems ALWAYS > directly benefit from being small and fast". Some do - for many, it is > irrelevant as long as they are small enough and fast enough. Once you > have reached the point of "good enough", anything more can often be > simply a waste of money and development time. > > Smaller code might mean you can use a cheaper microcontroller. Unless > you are nearing that point, however, making code smaller rarely helps. > Faster code might mean you can use a cheaper device, or slower speed > (lower EMI), or be in sleep mode more (lower power). Sometimes these > are important. Faster development (of the same quality code), however, > /always/ means cheaper engineering cost and if you get a faster time to > market, then for some products that means big commercial benefits. > > With that out of the way, the question is then whether C++ gives you > bigger or smaller code, faster or slower code, greater or lower > development costs in comparison to C. > > And the answer there is - it depends. > > If you don't know much about C++, using it is not going to be a benefit. > So that eliminates anyone who equates C++ and object-oriented coding. > If you are using an older or weaker C++ tool, it is likely to have a lot > of overhead. If you are using an older C++ standard (C++03 or before), > you lose out on many of the quality benefits of the language (just as > you do if you use C90 rather than C99 or C11). If you don't know how to > use your tools well, such as disabling RTTI and exceptions and using > optimisations, you will have a lot of overhead. (That applies to C > coding too, though marginally less so.) > > So lets assume you know what you are doing, as Trampas seems to. Start > with the obvious stuff - writing C code and compiling it with a C++ > compiler (with RTTI and exceptions disabled). What are the overheads > and costs? Nothing. Zero. > > Add in namespaces, strong enumerations, proper constants instead of > #define's, inline functions instead of macros. What are the overheads? > Zero. What are the benefits (in the hands of a good programmer)? > Clearer code, more chance of errors being caught by the compiler rather > than during testing (or after delivery to the customer). > > What about classes? What are the costs when you are not using virtual > functions, multiple inheritance, etc.? Nothing. What about when you > /are/ using virtual functions and the like? If you really need them > (usually you don't), then they can often be cheaper than equivalent code > in C using function pointers because the compiler can optimise them > better. Use them unnecessarily, then of course there is a cost. > > What about templates? The difference between template-generated code > and hand-written code is typically zero, but it can also give you > choices of a different balance between smaller object code or faster > object code (with more of the code being inlined). > > C++ gives more opportunities for misuse and bloat if you don't know how > to write C++ code for a small microcontroller. But if you /do/ know, it > lets you write significantly better quality code that is likely to be > more efficient, not less. > > The real cost of C++, as I experience it, is for debugging. You lose > the neat one-to-one relationship between functions in the source code > and functions in the object code that you used to get with old C > compilers. With a good C compiler (like avr-gcc) you already lose a lot > of that as the compiler inlines code and moves things around. But with > templated code, that effect is significantly amplified. > > David > > > On 11/04/2021 02:35, Bruce D. Lightner wrote: > > Trampas Stern, > > > > I'm sorry, but I've got to chime in here grasshopper. David Kelly put > > it well: just "don't use C++"! > > > > I somehow knew that this would start a flame war. :-) > > > > [FLAME ON] We've been there, done that, bought the T-shirt, here in > > forums like this before, going back many decades! I've heard all your > > silly platitudes repeatedly here and in other places---always coming > > from "wise fools" like yourself. > > > > IMNSHO putting your specious arguments "on the Internet" for all > > posterity to see is not the best move professionally. When I see > > statements like yours: > > > > /"Note that I have worked on projects in the past where we squeezed > > every clock and every byte out of a processor. However I have not > had to > > optimize for size or speed in 10 years. That is processors are so > cheap > > and powerful if you have to optimize code for size or speed then you > > most likely picked the wrong microprocessor." > > / > > > > ...you are definitely NOT ever going to be working with me. > > > > Why is plain old C still one of the most popular programming > > languages---number 1 by some measures (i.e., > > https://tiobe.com/tiobe-index/)? It's because commercial embedded > > systems ALWAYS directly benefit from small and fast. If you are a > > hobbyist you can make statements like you did. However us > professional > > C programmers that get paid the "big bucks" are in demand precisely > > because they can deliver products that run with minimal compute > > resources on the least expensive microcontrollers possible! > > > > And, yes one can reuse C code---I've been doing it for decades. > As for > > interrupt handlers and device drivers, between C macros and > > programmatically generated C code (e.g., Perl scripts) you can have it > > all without the "crutch" of C++ templates and class nonsense. > [FLAME OFF!] > > > > BTW: I suggest that you quit while you're ahead---but David and I > > somehow know that you won't! :-) > > > > Best regards, > > > > Bruce D. Lightner > > Lightner Engineering > > La Jolla, California > > light...@lightner.net <mailto:light...@lightner.net> > > https://www.linkedin.com/in/brucedlightner/ > > > > > ------------------------------------------------------------------------ > > On 4/10/2021 3:36 PM, Trampas Stern wrote: > >> Actually C++ is not slower or more bloat than C, depending on the > >> features used. > >> > >> For example I do not use RTTI or exceptions, so that makes it about > >> the same as C for size. Yes you have to turn these features off in > >> your compiler (-fno-rtti, -fno-exceptions). Sure you have > >> trampolines or jump tables for function overloading but you have > to do > >> the same in C. If you do not use inheritance or function > >> overloading you do not have the penalty. > >> > >> I find that in most of my embedded projects the cost of development > >> time is more than the cost of the processor for 5 years of > production, > >> that is the products are not super high volume products. As such, > >> reducing development time is very important. To this end I do > things > >> like write libraries and test them, and then reuse them. For example > >> I write an abstract interface class for a CharDevice, and > >> BlockDevice. Then a UART can be a CharDevice and EEPROM a > >> BlockDevice, SDCard is a BlockDevice, etc. This allows faster > >> development. Sure I can do this in C, but C++ basically does the > same > >> thing I would do in C and is easier to understand. > >> > >> Also things like templates are valuable, for example I wrote a FIFO > >> template. I debug that template once and never have to write fifo > >> code again. This is something very hard to do in C with any > >> efficiency. Now I can create a FIFO for uint8_t, uint32_t, or a > >> structure with one line. This can not be done easy in C. The same is > >> true for circular buffers and such... > >> > >> So yea C++ on embedded is very valid and real. I have been doing > >> professional embedded C for over 30 years and just switched to > C++ and > >> do not want to go back to C. The misconceptions about bloat are no > >> longer valid. Sure you can write bad C++ code using standard > >> templates and such but you can also write bad C code, so don't do > >> either. I think the misconception about C++ is because people try to > >> do stupid stuff like use cout, new, RTTI, exceptions, etc. Where > most > >> of the time the simple compile time features of C++ offer huge > >> advantages over C. > >> > >> At the end of the day all the compile time features of C++ are > >> free, like classes. There is zero reason not to use them because they > >> are free. The run time features are not free but you can choose what > >> you use, and turn off what you don't need. > >> > >> So yes I can write bad C++ code that is slow and bloated. I can write > >> bad C code that is slow and bloated. My job is to write functional > >> code that works and works correctly with no side effects and I can do > >> that faster and more efficiently in C++ using OO and minimal features > >> of C++. Maybe others can not, but that is not my problem. > >> > >> Note that I have worked on projects in the past where we squeezed > >> every clock and every byte out of a processor. However I have not had > >> to optimize for size or speed in 10 years. That is processors are so > >> cheap and powerful if you have to optimize code for size or speed > then > >> you most likely picked the wrong microprocessor. > >> > >> The problem with interrupt handlers which I asked about still exists > >> if you use C to write the code. That is you still have to map the > >> interrupt handler to the correct instance of the object unless > you are > >> insane and write a driver for each UART instance, which talking about > >> bloat and slow.... > >> > >> Trampas > >> > >> > >> > >> On Sat, Apr 10, 2021 at 5:12 PM David Kelly <dke...@hiwaay.net > <mailto:dke...@hiwaay.net> > >> <mailto:dke...@hiwaay.net <mailto:dke...@hiwaay.net>>> wrote: > >> > >> On Apr 10, 2021, at 2:37 PM, Trampas Stern <tst...@nc.rr.com > <mailto:tst...@nc.rr.com> > >> <mailto:tst...@nc.rr.com <mailto:tst...@nc.rr.com>>> wrote: > >> > >>> If you guys have a better way I would love to know. > >> > >> Don’t use C++? > >> > >> What does object-oriented coding do for embedded projects? It’s > >> akin to using printf(). Slow and lots of bloat. > >> > >> Time once was I put uint32 in a union so as to code ++ inline > >> rather than let avr-gcc call a library routine. Even more so > if in > >> an interrupt. Not all library routines used to be re-entrant. > >> > >> -- > >> David Kelly N4HHE, dke...@hiwaay.net > <mailto:dke...@hiwaay.net <mailto:dke...@hiwaay.net>> > >> ============================================================ > >> Whom computers would destroy, they must first drive mad. > >> > > > > > > /CONFIDENTIALITY NOTICE: This e-mail and any attachments may contain > > confidential information intended solely for the use of the addressee. > > If the reader of this message is not the intended recipient, any > > distribution, copying, or use of this e-mail or its attachments is > > prohibited. If you received this message in error, please notify the > > sender immediately by e-mail and delete this message and any copies. > > Thank you./ >