Dave Nadler wrote:> On Tuesday, October 21, 2014 1:12:15 PM UTC-4, Stefan Reuther wrote: >>What helps me most is that I am able to think like a compiler, because I >>wrote half of one during university. Few people can do that (and it >>isn't a skill that embedded recruiters have on their list). So while >>most people can get a program correct after a while, only few can make >>it efficient. > > Um, you think like half a compiler ? ;-) > Really, for C++ it is necessary to understand what happens > under the hood (contrary to the definition of a good tool), > but how the compiler works??Things like: what information does the compiler have at this point? What information would it need to do this transformation? What border cases does it have to handle? This leads to consequences such that it has to generate an exception handling frame here because it cannot prove that this trivial function never throws, that it has to instantiate (and thus has to see) this template here because it cannot assume anything about it being instantiated elsewhere, or that 'std::string s = a+b+c+d;' creates an uncomfortable number of temporaries whereas 'std::string s = a; s += b; s += c; s += d;' does not. Call it "what happens under the hood" or "how does the compiler think", the idea is the same.>>>2) In a small embedded system with no dynamic memory >>>(other than the stack): >>>2a) What language features will you not be able to use? >> >>This is a trick question, because if I don't have dynamic memory, I >>could simply write my own allocator. > > No, it is not a trick question, and that is NOT the answer...Why not? C++ at least makes it a language feature and a library feature to make my own allocator. But if I cannot use 'new' and 'delete' the answer simply becomes: "I cannot use the language features 'new' and 'delete'" :-) I also cannot use most of the STL, but that's not a core language feature.>>>2b) What special considerations will you expect when >>>creating a class? >> >>Depends on the compiler, but I would try to convince the compiler NOT to >>generate exception-handling code. > > Why does it depend on the compiler??Because on some compilers this is the matter of just flipping a switch, so I can use my already-written classes; on others I'd have to write special exception-less code to avoid that the compiler generates code I do not want.>>This could mean not using destructors, >>and maybe even constructors. > > No, no, no... > What else?What else are you expecting? Other memory saving techniques like using bitfields ("enum {...} foo : 8" to save 3 bytes) are not C++-specific, and apply to C as well.>>For a previous project, I was writing several drivers; some already >>existed in a prototype version in C. Drivers needed some sort of >>request/result queues. The C versions implemented these queues anew, >>every damn time, probably with a lot of cut & paste involved. First >>thing I did was to add a simple Queue template class and use it >>everywhere. My final source code was around half the size and much more >>maintainable than the C version; the object code was smaller by a few >>percent, too. > > A good example of C++ helping! > However, some would argue you should have implemented the queue code > once using void* (and maybe item size), then wrapped it with inlines > using specific names/types for safety.In this particular case, the class went roughly like this: template<typename T, size_t N> class Queue { void post(const T& t) { m_elems[m_head++ % N] = t; } T get() { return m_elems[m_tail++ % N]; } T m_elems[N]; size_t m_head, m_tail; }; (details omitted) where each function generates a few machine instructions only. Adding a void* and a size_t would only have made matters more complicated.> Hopefully you wrote a unit test for your template before using it!Well, I did that before using it in the next project, where we finally hat infrastructure for making unit tests in the build system :) Stefan
validity of ... reasons for preferring C over C++
Started by ●October 16, 2014
Reply by ●October 22, 20142014-10-22
Reply by ●October 22, 20142014-10-22
Am 22.10.2014 um 01:39 schrieb Paul Rubin:> Interesting point about iostreams. I haven't really looked into the > bloat cause. I know that everything on 64 bit systems is big. I've > idly thought about compiling the program on a 32 bit system to see if it > comes out smaller.Just in case, let me throw in a side note: you almost certainly don't have to go as far as compiling "on" a 32-bit system to achieve that. It will be quite sufficient to compile _for_ a 32-bit system. I.e. all you need is a cross-compiler for a 32-bit target platform (e.g. Win32 instead of Win64).> The philosophy of C++ seems to be to generate fast > code above everything else. When there is a trade-off between code size > and speed, it will bloat the code to get more speed.I don't really think that's true for C++ as a language. It may well be a true statement about people programming in C++, though. There was a time when compiler technology didn't manage to keep up with the demands of the C++ language specification. Template instantiation created a whole lot of new and interesting problems, which took quite a while to sort out. Linkers in particular have to be a whole lot better than they used to, otherwise the sizes of C++ programs liberally utilizing templates would have exploded beyond all reason.
Reply by ●October 23, 20142014-10-23
On Wednesday, October 22, 2014 12:30:24 PM UTC-4, Paul Rubin wrote:> Dave Nadler <drn@nadler.com> writes: > > Bad because in a resource constrained environment, > > qsort can chew up more stack than is available. > > You might have been using a broken implementation of quicksort, that > didn't make sure to sort the smaller partition first in its recursive > step. That keeps the stack use at O(log N) instead of potentially O(N), > which in some really bad implementations can happen if the vector is > already sorted.Even at O(log N), qsort chews up a lot of stack space for non-trivial N. heapsort is more appropriate in a resource-constrained environment... Hope I don't find another one of those! Best Regards, Dave
Reply by ●October 23, 20142014-10-23
Dave Nadler <drn@nadler.com> writes:> Even at O(log N), qsort chews up a lot of stack space for non-trivial N. > heapsort is more appropriate in a resource-constrained environment...In an environment so resource-constrained that log N is consequential, you aren't going to fit a non-trivial N anyway. So you may as well use quicksort. ;-).
Reply by ●October 23, 20142014-10-23
Paul Rubin <no.email@nospam.invalid> wrote:> Dave Nadler <drn@nadler.com> writes: >> Even at O(log N), qsort chews up a lot of stack space for non-trivial N. >> heapsort is more appropriate in a resource-constrained environment...> In an environment so resource-constrained that log N is consequential, > you aren't going to fit a non-trivial N anyway. So you may as well use > quicksort. ;-).Yes, but even better, write quicksort without using actual recursion. (The stack has to hold arguments and return addresses, which even for small log(N) adds up.) An array of log2(memory size) won't be all that big. You do have to be sure to do the partitions in the right order, though. -- glen
Reply by ●October 23, 20142014-10-23
glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:> Yes, but even better, write quicksort without using actual recursion.Yes, that's normal, use an explicit stack in the code rather than recursion. It's still O(log N) but you don't have to save as much stuff on the stack as recursion would use.
Reply by ●October 24, 20142014-10-24
>> Yes, Stroustrup keeps saying that it's perfectly well suited to the >> small device space, and there's not a serious reason it shouldn't be, >> if you program in a constrained style.I agree as far as the *language* is concerned, but the standard *libraries* are almost useless for a small real-time system. The biggest problem that they were created with the desktop mindset: "memory is cheap and plenty, average performance is what counts, and resource shortage must be met with graceful degradation". This leads to libraries that use the heap and exceptions, and have good avarage but bad worst-case performance. Exactly what you *don't* want on a small rea-time embedded system.> I have been playing with embedded c++11, just some toy programs on ARM > microcontroller development boards at the moment. The minimum footprint > was only a few kB, it seems absolutely fine for even the smallest > projects (that I would be interested in anyway). Even using some STL and > vectors and strings and so forth seemed to work without doing anything > too dramatic to the code size.My C++ blink-a-led built for the LPC1114 uses 232 bytes code. OK, that is without heap, exceptions, and global objects, but I don't want those on a small uc anyway. Wouter van Ooijen
Reply by ●October 27, 20142014-10-27
On Thursday, October 23, 2014 6:17:36 PM UTC-4, Paul Rubin wrote:> Dave Nadler <drn@nadler.com> writes: > > Even at O(log N), qsort chews up a lot of stack space for non-trivial N. > > heapsort is more appropriate in a resource-constrained environment... > > In an environment so resource-constrained that log N is consequential, > you aren't going to fit a non-trivial N anyway. So you may as well use > quicksort. ;-).Um, in this case N was ~900. Stack space is especially constrained in segmented architectures; in this case the data to be sorted was "far". Rather than chewing up stack (or static data) for qsort, use heapsort! Hope that is helpful, Best Regards, Dave
Reply by ●October 27, 20142014-10-27
Dave Nadler <drn@nadler.com> writes:> Um, in this case N was ~900. Stack space is especially constrained > in segmented architectures; in this case the data to be sorted > was "far".Well if you use an explicit stack rather than recursion, you could put it in far memory as well.
Reply by ●October 27, 20142014-10-27
On Monday, October 27, 2014 12:00:47 PM UTC-4, Paul Rubin wrote:> Dave Nadler <drn@nadler.com> writes: > > Um, in this case N was ~900. Stack space is especially constrained > > in segmented architectures; in this case the data to be sorted > > was "far". > > Well if you use an explicit stack rather than recursion, you could put > it in far memory as well.Why would I do that, when heapsort requires NO additional memory??







