On 08/11/16 23:47, Wouter van Ooijen wrote:
> Op 08-Nov-16 om 7:34 PM schreef bitrex:
>> I've read that contrary to popular belief, it's quite feasible to write
>> effective C++ code for small microprocessors without MMUs such as the
>> low-tier ARMs, and even AVR 8-bits with only say a couple kilobytes of
>> working memory.
>
> Actually there are quite a few persons that actively promote using (a
> suitable part of) C++ on small microcontroller.
>
> The main problem with AVRs is that they don't have a unified address
> space, so you can't have a pointer that can point to ROM or RAM. This
> makes consexpr much less effecitive.
It is more of a problem for const than constexpr. constexpr code can be
figured out at compile time (assuming all the parameters are known at
compile time), and the AVR will have no problem dealing with the
results. The challenge for the AVR is when you have const data that you
would like to be held in flash (since the chips have limited ram space)
- it takes different code to read the data from flash than it does to
read it from ram.
A second key problem on the AVR is that it has very poor pointer
support, and poor "stack + offset" addressing. This quickly means that
a lot of neat, structured C++ code with pointers, references, etc.,
becomes quite inefficient compared to code using static variables. This
applies to C as well, but in C++ you regularly have a "*this" pointer as
well.
And libstdc++ is not implemented in avr-gcc as yet. This means no
standard C++ classes, no new and delete, no exceptions. But you still
get strong typing, templates, namespaces, constexpr, classes, etc. (I
wonder if lambdas work?)
>
>> That the code size for some constructs using say avr-g++ can actually
>> end up smaller than attempting to write something equivalent in straight
>> C, simply due to the more "expressive" syntax.
>
> Templates are your friend (if used well). So is whole-program
> optimization. And constexpr!
Or LTO, as it is now - "-fwhole-program" is out of fashion. LTO has its
challenges with debugging, however.
>
>> Clearly not all subsets of the language will be feasible to use on such
>> limited hardware, without a MMU dynamic memory allocation becomes much
>> more problematic
>
> Why? You can have a hep in 2k RAM if you want. The main reasons the heap
> is mostly not used in small systems are:
> - unpredictable real-time performance
> - fragmentation
> - not knowing upfront whether everything will fit
Agreed. I don't see why an MMU would be an issue here. An MMU can be
useful to reduce fragmentation on a larger scale (such as 4K pages), but
it is hardly helpful if you have 4K ram in total!
>
>> , everything should be instantiated at execution (or at
>> least appropriate fixed-size buffers should be allocated), stuff like
>> unique_ptr and other allocation management features of C++11 and later
>> are certainly out, and the implementations I've seen of the STL for such
>> architectures are definitely not entirely C++11 compatible.
>>
>> The performance hit of some types of template metaprogramming and
>> vtables of polymorphism is also a question.
>
> The performance penalty of template metaprogramming occurs at
> compile-time, so that is a big win!
People often mistakenly believe that templates mean code bloat. When
used correctly, and with good tool support, templates can reduce code size.
>
> V-tables and run-time polymorphism are a great tool *if you need it*. If
> you can live with compile-time polymorphism templates can deliver that
> at zero run-time cost.
>
>> My question is, what would you take from say C++11, and what would you
>> leave?
>
> Give me C++17 or better 20 (concepts, finally?).
>
> Leaving something out of the language is not a good idea. That would
> split the language community and introduce backwards incompatibility.
>
> What I do like is a library that doesn't *force* me to use
> - exceptions
> - heap
> - RTTI
> - floating point
> when I don't need it. So I'd like to see fixed-maximum-size containers
> and string.
Agreed.
>
> And I'd like to see toolchain flags that ensure that those features are
> not used (some are already available). And as for toolchains: I'd like
> to have a limited stack size, and warnings when the compiler can't
> determine the stack size.
Agreed. The more warnings you can get at compile time, the better.
> And I hate ctors, so I'd like an option to
> make those a warning too. (I can detect them at link time, but that
> amkes it difficult to find back the offending source line).
That one I don't get. You hate constructors? They are pretty essential
to the whole concept of classes, and to RAII in particular.
The only thing that is a mess is the global constructor order problem.
It would be nice to have a /real/ solution to that one. Ideally, if a
global/static object's constructor refers to another global/static
object, then the referred-to object should be ordered earlier in the
constructor list. Then it should all be safe.