EmbeddedRelated.com
Forums
Memfault Beyond the Launch

CPU recommendations?

Started by Unknown March 23, 2009
On Tue, 31 Mar 2009 11:37:09 +0200
David Brown <david@westcontrol.removethisbit.com> wrote:

> [snip] > All in all, templates have the potential for huge benefits for > programs, but it is *not* easy to write a good template library.
It's not even easy to _work with_ a good template library. The STL is, all grousing aside, pretty good. It's stable, well documented, provides lots of useful functionality, etc. Oh, yes, and makes your code entirely and completely illegible, even to other STL familiar programmers. To anyone who's not, it makes the syntax of things so obtuse that they can't even tell what language it's in. -- Rob Gaddi, Highland Technology Email address is currently out of order
"David Brown" <david@westcontrol.removethisbit.com> wrote in message 
news:49d1bd10$0$14950$8404b019@news.wineasy.se...
> Steve at fivetrees wrote: >> "David Brown" <david@westcontrol.removethisbit.com> wrote in message >> news:49d0b1a2$0$14785$8404b019@news.wineasy.se... >>> There are certainly good reasons for using C++ in such small systems - >>> done well, classes, templates, and stronger typing can give you a better >>> development environment (clearer and safer source code and at least as >>> small and fast object code). The problem with C++ in such systems is >>> that there are very few developers who know how to use C++ well... >> >> Have to disagree with you there. >> > > On which part - the idea that C++ *can* lead to better source code than C, > or that very few C++ developers can actually write C++ that is better than > a typical C program on a small micro?
I'm not sure I believe either of those premises (that C++ can generate better source code, or better than C on a small micro) ;). (And I'm glad I left it a few days before elaborating.) First, I plain don't like C++. Let me be upfront and frank about that. I *do* like OO, but consider C++ to be a poor/primitive implementation. If you want reasons, I'll start with the fact that, in C++, class declarations (mostly) belong in header files. So much for privacy, eh? I'll absolutely grant you the fact that significant C++ chops are needed to be able to do it even slightly well. And there's a lot of awful C++ code around. (I'll put the fact that I've seen coders debugging code with *every* header file open, trying to understand where the original overloaded/inherited declaration was, in that basket.) On a desktop machine, I'll happily defer to the guys I work with, who do wonders with C++ every day. But on embedded targets (more my area), I have an aversion to any use of malloc/new, and to any form of late binding. Or indeed of private methods/variables in header files. Amongst other things. I tend to write (embedded) code in object-oriented (or orientated, for the pedants ;)) C. Plain old C. For me, the design is the key thing, and the code is a reflection of the design. I can do most things (except for multiple inheritance, which is dodgy idea anyway...) in plain C - if it's designed a particular way, I can probably code it - in C or assembler, without loading up the runtime with stuff it really doesn't need to do, and which might fail. Failure is not an option on embedded targets.
> One only has to look at the C++ features that have been copied into C > (examples include "inline", \\comments, and mixing variable declarations > and code) to see that there are features from C++ that are of benefit to C > code and C programmers.
I agree with that, but most (well, some) of those details have been ported over to plain ol' C. They don't depend on C++. They're just improvements.
> I have certainly come across parts of my C coding where I have thought it > would be far neater and clearer to use classes - mostly just for > encapsulation (which is really just syntactic sugar - lcd.init() instead > of lcdInit()), but sometimes with inheritance (single and non-virtual, of > course). I've also seen the benefits of RAII for things like an > interrupt-disabler class, and I've seen templates that provide neat and > flexible interfaces to things like port IO pins, while generating ideal > assembly code in the end.
Indeed - and again I'd do the same thing with OO C.
> I haven't switched to C++ because I don't have the experience to do it > well, but if I ever get the time to learn it properly, I will.
Your honesty noted and admired. For me, C++ is a valiant attempt, but just plain broken. Now - if someone were to come up with a new version of C which understands classes, and (emphasis) *led to clearer code*, I'd be right there. C++ ain't it. My main objective in writing code these days is clarity, clarity, and yet more clarity. Beyond a certain point, I've learned that a die-shrink is more likely to speed up my code than endless optimisation. Similarly, I've learned that keeping things simple and modular, and using more vertical hierarchy than horizontal cuteness, results in faster and clearer code. Again, it's down to design rather than coding. I admit that we tend to do both things together these days. But again,C++ is *not* (IMHO) a good tool - it's the right idea, but badly done. Time for a revision. Ada, anyone? Your turn ;). Steve -- http://www.fivetrees.com
"Steve at fivetrees" <steve@NOSPAMTAfivetrees.com> wrote in message 
news:-pmdnY01ZOTnfU7UnZ2dnUVZ8u6dnZ2d@pipex.net...
> Again, it's down to design rather than coding. I admit that we tend to do > both things together these days. But again,C++ is *not* (IMHO) a good > tool - it's the right idea, but badly done. Time for a revision. Ada, > anyone? >
Have you investigated Oberon? The Oberon-07 that I use for embedded systems programming does not include all of the OO-specific features of Oberon-2 or Component Pascal but it also doesn't suffer from the C++ flaws that you mentioned. You will find all of the details here: http://www.inf.ethz.ch/personal/wirth/Articles/Oberon.html -- Chris Burrows CFB Software Armaide: ARM Oberon-07 Development System for Windows http://www.cfbsoftware.com/armaide
Steve at fivetrees wrote:
> First, I plain don't like C++. Let me be upfront and > frank about that.
Noted. (Don't be afraid children ... C++ is just a toolbox.)
> I *do* like OO, but consider C++ to be a poor/primitive > implementation.
So you want to code C++ features by hand? Hand coded vtables? How do you code templates?
> If you want reasons, I'll start with the > fact that, in C++, class declarations (mostly) belong in > header files. So much for privacy, eh?
You can put class declarations any where you like. Of course, if you want to share them among other files/modules, then you need to put them in header files. The struct and union constructucts in C work the same way. What is the problem? What better privacy can you achieve with C that you are unable to accomplish with C++?
> I'll absolutely grant you the fact that significant > C++chops are needed to be able to do it even slightly > well.
Yep. C++ is a powerful, non-trivial tool-kit with many *optional* facilities, including compatability with C.
> And there's a lot of awful C++ code around.
Amen.
> But on embedded targets (more my area), I have an > aversion to any use of malloc/new,
For some embedded systems, Malloc/new is convenient at initialization. However, free/delete are not OK for mine (heap fragmentation.) Placement *new* is a great tool.
> and to any form of late binding.
What in the world is wrong with late binding? I guess you don't like function pointers either.
> Or indeed of private methods/variables in header files.
There is no need to put them there unless of course there is a good reason to put them there. How do you do this better in C ?
> I tend to write (embedded) code in object-oriented (or > orientated, for the pedants ;)) C. Plain old C.
Is that the same thing as using a hammer to drill a hole?
> For me, the design is the key thing, and the > code is a reflection of the design.
Agreed.
> I can do most things (except for multiple inheritance, > which is dodgy idea anyway...) in plain C - if it's > designed a particular way,
Generally speaking, composition is "better" for many problems, but MI (especially interface inheritance) has its place.
> I can probably code it - in C or assembler, without > loading up the runtime with stuff it really doesn't need > to do, and which might fail. Failure is not an option on > embedded targets.
Failure is indeed not an option in most embedded targets. What runtime stuff are you talking about? RTTI? Exceptions? I don't use/allow either of those. RTTI is just plain evil. Exceptions would be nice if they were implemented in a way that does not include dynamic memory allocation. I have never encountered such an implementation :( One of the great things about C++ is that the language itself doesn't penalize you for features you don't use.
>> I have certainly come across parts of my C coding where >> I have thought it would be far neater and clearer to >> use classes - mostly just for encapsulation (which is >> really just syntactic sugar - lcd.init() instead of >> lcdInit()), but sometimes with inheritance (single and >> non-virtual, of course). I've also seen the benefits of >> RAII for things like an interrupt-disabler class, and >> I've seen templates that provide neat and flexible >> interfaces to things like port IO pins, while >> generating ideal assembly code in the end. > > Indeed - and again I'd do the same thing with OO C.
With more (error prone) work? E.g. hand coding inheritance (function tables.)
>> I haven't switched to C++ because I don't have the >> experience to do it well, but if I ever get the time to >> learn it properly, I will. > > Your honesty noted and admired. For me, C++ is a valiant > attempt, but just plain broken.
Do you mean C++ is broken or it's ugly? How is C++ broken? It works quite well for me.
> Now - if someone were to come up with a new version of C > which understands classes, and (emphasis) *led to clearer > code*, I'd be right there. C++ ain't it.
C++ "understands" classes. Obfuscation can be accomplished in any syntax. Using C to implement C++ features *decreases* clarity, if for no other reason than more code is required to accomplish the same goal. Using the same argument, you should be writing assembler instead of C.
> My main objective in writing code these days is clarity, > clarity, and yet more clarity.
Clarity is good. Clarity at the module/file level is possible. Clarity at the inter-module level requires external documentation.
> Beyond a certain point, I've learned that a die-shrink is > more likely to speed up my code than endless > optimisation.
Yep. Something about premature optimisation and evil :)
> Similarly, I've learned that keeping things simple and > modular, and using more vertical hierarchy than > horizontal cuteness, results in faster and clearer code.
Yep. Consistent naming/terminology combined with the use of design patterns works wonders. -- Michael N. Moran (h) 770 516 7918 5009 Old Field Ct. (c) 678 521 5460 Kennesaw, GA, USA 30144 http://mnmoran.org "So often times it happens, that we live our lives in chains and we never even know we have the key." "Already Gone" by Jack Tempchin (recorded by The Eagles) The Beatles were wrong: 1 & 1 & 1 is 1
Chris Burrows wrote:
> "Steve at fivetrees" <steve@NOSPAMTAfivetrees.com> wrote in message > news:-pmdnY01ZOTnfU7UnZ2dnUVZ8u6dnZ2d@pipex.net... >> Again, it's down to design rather than coding. I admit that we tend to do >> both things together these days. But again,C++ is *not* (IMHO) a good >> tool - it's the right idea, but badly done. Time for a revision. Ada, >> anyone? >> > > Have you investigated Oberon? The Oberon-07 that I use for embedded systems > programming does not include all of the OO-specific features of Oberon-2 or > Component Pascal but it also doesn't suffer from the C++ flaws that you > mentioned. You will find all of the details here: > > http://www.inf.ethz.ch/personal/wirth/Articles/Oberon.html >
Although I see there is an ARM Oberon compiler, it's not really aimed at embedded systems (it seems to have been targeted at the StrongARM originally), and there certainly is nothing for other embedded devices. It's an interesting language, however.
Steve at fivetrees wrote:
> "David Brown" <david@westcontrol.removethisbit.com> wrote in message > news:49d1bd10$0$14950$8404b019@news.wineasy.se... >> Steve at fivetrees wrote: >>> "David Brown" <david@westcontrol.removethisbit.com> wrote in message >>> news:49d0b1a2$0$14785$8404b019@news.wineasy.se... >>>> There are certainly good reasons for using C++ in such small systems - >>>> done well, classes, templates, and stronger typing can give you a better >>>> development environment (clearer and safer source code and at least as >>>> small and fast object code). The problem with C++ in such systems is >>>> that there are very few developers who know how to use C++ well... >>> Have to disagree with you there. >>> >> On which part - the idea that C++ *can* lead to better source code than C, >> or that very few C++ developers can actually write C++ that is better than >> a typical C program on a small micro? > > I'm not sure I believe either of those premises (that C++ can generate > better source code, or better than C on a small micro) ;). (And I'm glad I > left it a few days before elaborating.) >
So we definitely agree on the second part - that there are few developers that can write good C++ on embedded systems! I don't count myself as a good C++ programmer - I have not had nearly enough experience with it, and certainly not for real-world projects.
> First, I plain don't like C++. Let me be upfront and frank about that. I
I don't like C++ either, for much the same reasons you don't like it. But that doesn't mean you get some benefits from it. To paraphrase Churchill, C is the worst possible language, but it's the best we've got. C has so many design faults there is no space to list them here (but I'll mention the obsession with "int", the horror that is the preprocessor instead of decent module support, and the typo-friendly "if" and "switch" constructs). Yet I write code (at least some of which is good quality :-) in C all the time. Imagine you were to give code a "goodness" rating encompassing the clarity of the source code, the maintainability and portability of the code, and the speed and compactness of the generated object code. I would say that for small embedded systems C++ would let you improve that rating by 30% - it also easily lets you drop it by 90% (a single virtual inheritance will make an AVR run like an 8051, and multiple inheritance will turn your source code into Greek). I would also say that the average embedded C++ programmer (from what I have seen) will hit the average spot - i.e., a 30% drop in "goodness" compared to what they could have done in C.
> *do* like OO, but consider C++ to be a poor/primitive implementation. If you > want reasons, I'll start with the fact that, in C++, class declarations > (mostly) belong in header files. So much for privacy, eh? >
I agree 100% here. I'd also add that multiple inheritance is a terrible idea. There are a few occasions when it is genuinely better than simply including subobjects in your class - but these uses are far outweighed by the costs and complications of multiple inheritance. (If you are a Python fan, there is one *good* use of multiple inheritance - for mixin classes. But these rely on duck typing, which C++ does not have.)
> I'll absolutely grant you the fact that significant C++ chops are needed to > be able to do it even slightly well. And there's a lot of awful C++ code > around. (I'll put the fact that I've seen coders debugging code with *every* > header file open, trying to understand where the original > overloaded/inherited declaration was, in that basket.) On a desktop machine, > I'll happily defer to the guys I work with, who do wonders with C++ every > day. But on embedded targets (more my area), I have an aversion to any use > of malloc/new, and to any form of late binding. Or indeed of private > methods/variables in header files. Amongst other things. >
Again, I agree with you here. In particular, the declaration of private code/data in header files is one point where using C++ classes take a step backwards from C's "everything in the global namespace or static to a file" visibility.
> I tend to write (embedded) code in object-oriented (or orientated, for the > pedants ;)) C. Plain old C. For me, the design is the key thing, and the > code is a reflection of the design. I can do most things (except for > multiple inheritance, which is dodgy idea anyway...) in plain C - if it's > designed a particular way, I can probably code it - in C or assembler, > without loading up the runtime with stuff it really doesn't need to do, and > which might fail. Failure is not an option on embedded targets. > >> One only has to look at the C++ features that have been copied into C >> (examples include "inline", \\comments, and mixing variable declarations >> and code) to see that there are features from C++ that are of benefit to C >> code and C programmers. > > I agree with that, but most (well, some) of those details have been ported > over to plain ol' C. They don't depend on C++. They're just improvements. > >> I have certainly come across parts of my C coding where I have thought it >> would be far neater and clearer to use classes - mostly just for >> encapsulation (which is really just syntactic sugar - lcd.init() instead >> of lcdInit()), but sometimes with inheritance (single and non-virtual, of >> course). I've also seen the benefits of RAII for things like an >> interrupt-disabler class, and I've seen templates that provide neat and >> flexible interfaces to things like port IO pins, while generating ideal >> assembly code in the end. > > Indeed - and again I'd do the same thing with OO C. >
It is possible to write OO in C - I've even written OO assembly code. But you have to admit that C++ can make it a little easier.
>> I haven't switched to C++ because I don't have the experience to do it >> well, but if I ever get the time to learn it properly, I will. > > Your honesty noted and admired. For me, C++ is a valiant attempt, but just > plain broken. Now - if someone were to come up with a new version of C which > understands classes, and (emphasis) *led to clearer code*, I'd be right > there. C++ ain't it. >
Again, I agree - it is possible to do *far* better than C++ in designing an OO language. But C++ is the best we have at the moment, and when used well, it can be better than C. But if I were designing an ideal language for embedded design, which would include OO, I wouldn't start from C.
> My main objective in writing code these days is clarity, clarity, and yet > more clarity. Beyond a certain point, I've learned that a die-shrink is more > likely to speed up my code than endless optimisation. Similarly, I've > learned that keeping things simple and modular, and using more vertical > hierarchy than horizontal cuteness, results in faster and clearer code. > Again, it's down to design rather than coding. I admit that we tend to do > both things together these days. But again,C++ is *not* (IMHO) a good tool - > it's the right idea, but badly done. Time for a revision. Ada, anyone? > > Your turn ;). >
I can't really argue with you when we agree on most of the points - it's really only a difference in weightings and nuances.
Michael N. Moran wrote:
> Steve at fivetrees wrote: >> First, I plain don't like C++. Let me be upfront and frank about that. > > Noted. > > (Don't be afraid children ... C++ is just a toolbox.) > >> I *do* like OO, but consider C++ to be a poor/primitive >> implementation. > > So you want to code C++ features by hand? > Hand coded vtables? > How do you code templates? >
I'd guess he means something like: void runMotor(motor *mp) { if (mp->isBig) runBigMotor(mp); else runSmallMotor(mp); } That sort of thing is perfectly possible. It's not as scalable as using C++ class hierarchies, but on the other hand you have all the relevant code in one place.
>> If you want reasons, I'll start with the >> fact that, in C++, class declarations (mostly) belong in >> header files. So much for privacy, eh? > > You can put class declarations any where you like. > Of course, if you want to share them among other > files/modules, then you need to put them in header > files. The struct and union constructucts in C work > the same way. What is the problem? > > What better privacy can you achieve with C that > you are unable to accomplish with C++? >
In C, your header file might contain: extern void startMotor(void); extern int motorSpeedTarget; And the C file contains: static void runMotor(void); static int currentSpeed; With C++, your header file has the class definition : class Motor { public : void start(void); int speedTarget; private: void run(void); int currentSpeed; } There is no excuse for designing an OO language in which code and data that is explicitly reserved for private use within a class implementation must be publicly exposed in the interface definition. It's bad design in the language, and there are no good, efficient ways to avoid it. The same applies to things like inline functions - they are critical to getting code quality generated code while maintaining an abstract interface, but it means that these implementation details end up in the interface file (the header). The common "workaround" for this is that your C++ program is actually compiled by a driver C++ file that #include's all the other C++ files in the project! Of course, you can use abstract base classes - if you are willing to pay the cost.
>> I'll absolutely grant you the fact that significant >> C++chops are needed to be able to do it even slightly >> well. > > Yep. C++ is a powerful, non-trivial tool-kit with many > *optional* facilities, including compatability with C. >
Absolutely. My point all along is that although C++ has many failings, if you use parts of it, and use them carefully, you can get a great deal of benefit for relatively little cost (the header privacy issue being one of these costs).
>> And there's a lot of awful C++ code around. > > Amen. > >> But on embedded targets (more my area), I have an aversion to any use >> of malloc/new, > > For some embedded systems, Malloc/new is convenient > at initialization. However, free/delete are not OK > for mine (heap fragmentation.) > Placement *new* is a great tool. >
Agreed - it's free/delete that is the big issue, rather than malloc/new. But it is much better to have fixed static allocation in small systems - access to linker-allocated addresses is faster (that's different on bigger processors, where the difference is minor).
>> and to any form of late binding. > > What in the world is wrong with late binding? > > I guess you don't like function pointers either. >
Late binding is good if you really need it - virtual method accesses are not much different from function pointers (though there might be an extra indirection hidden). But you don't often need it - and with C++ it's easy to get accidental late binding. On big systems, there are certain habits and rules such as "always make your destructors virtual", and if these are carried over to embedded systems they quickly add unnecessary overhead. The point here is not that C++ forces you to have such overhead, but that it takes a good programmer to make sure they don't do that sort of thing by mistake.
>> Or indeed of private methods/variables in header files. > > There is no need to put them there unless of course > there is a good reason to put them there. How do you > do this better in C ? > >> I tend to write (embedded) code in object-oriented (or >> orientated, for the pedants ;)) C. Plain old C. > > Is that the same thing as using a hammer to drill a hole? > >> For me, the design is the key thing, and the code is a reflection of >> the design. > > Agreed. > >> I can do most things (except for multiple inheritance, which is dodgy >> idea anyway...) in plain C - if it's designed a particular way, > > Generally speaking, composition is "better" for many > problems, but MI (especially interface inheritance) > has its place. > >> I can probably code it - in C or assembler, without loading up the >> runtime with stuff it really doesn't need >> to do, and which might fail. Failure is not an option on >> embedded targets. > > Failure is indeed not an option in most embedded targets. > > What runtime stuff are you talking about? RTTI? Exceptions? > I don't use/allow either of those. RTTI is just plain evil. > Exceptions would be nice if they were implemented in a way > that does not include dynamic memory allocation. I have > never encountered such an implementation :( > > One of the great things about C++ is that the language > itself doesn't penalize you for features you don't use. >
This ties in with what I've been saying - if you know what you are doing, know the costs of using features, and know what's important in the design, then you can get a lot of benefit from C++. Things like RTTI and exceptions give little value for money (or source code clarity or generated code quality), especially in small systems.
>>> I have certainly come across parts of my C coding where >>> I have thought it would be far neater and clearer to >>> use classes - mostly just for encapsulation (which is >>> really just syntactic sugar - lcd.init() instead of >>> lcdInit()), but sometimes with inheritance (single and >>> non-virtual, of course). I've also seen the benefits of >>> RAII for things like an interrupt-disabler class, and >>> I've seen templates that provide neat and flexible >>> interfaces to things like port IO pins, while >>> generating ideal assembly code in the end. >> >> Indeed - and again I'd do the same thing with OO C. > > With more (error prone) work? E.g. hand coding > inheritance (function tables.) > >>> I haven't switched to C++ because I don't have the experience to do >>> it well, but if I ever get the time to >>> learn it properly, I will. >> >> Your honesty noted and admired. For me, C++ is a valiant attempt, but >> just plain broken. > > Do you mean C++ is broken or it's ugly? > How is C++ broken? It works quite well for me. >
It's certainly ugly (look at the template syntax, or the "new style" cast syntax). It is certainly broken in several ways - the lack of a clear interface/implementation boundary is a major point. Templates are broken - there is no consensus on whether these should be in headers or cpp files, there is no language-defined way to control or discover what code is generated or used for templates, and there is no consistency in error checking and reporting when using templates. Multiple inheritance is broken - it shouldn't be there in the first place, or it should be done properly (allowing a "sorted list of triangles" to inherit from both "list" and "shape"). Overloading is broken - there should be a way to handle overloading based on return types, and ways to handle ambiguous overloading. And of course there are mistakes in C that C++ has inherited, like int promotion that screws with overloading. This doesn't mean that C++ doesn't work - but it could have been so much better.
>> Now - if someone were to come up with a new version of C which >> understands classes, and (emphasis) *led to clearer >> code*, I'd be right there. C++ ain't it. > > C++ "understands" classes. > Obfuscation can be accomplished in any syntax. >
C++ gives new ways to avoid obfuscation, and new ways to implement it.
> Using C to implement C++ features *decreases* > clarity, if for no other reason than more code > is required to accomplish the same goal. > > Using the same argument, you should be writing > assembler instead of C. > >> My main objective in writing code these days is clarity, >> clarity, and yet more clarity. > > Clarity is good. > Clarity at the module/file level is possible. > Clarity at the inter-module level requires > external documentation. > >> Beyond a certain point, I've learned that a die-shrink is >> more likely to speed up my code than endless >> optimisation. > > Yep. Something about premature optimisation and evil :) > >> Similarly, I've learned that keeping things simple and >> modular, and using more vertical hierarchy than >> horizontal cuteness, results in faster and clearer code. > > Yep. > Consistent naming/terminology combined with the use > of design patterns works wonders. > >
"David Brown" <david@westcontrol.removethisbit.com> wrote in message 
news:49d461ac$0$22014$8404b019@news.wineasy.se...
> Chris Burrows wrote: >> >> Have you investigated Oberon? The Oberon-07 that I use for embedded >> systems programming does not include all of the OO-specific features of >> Oberon-2 or Component Pascal but it also doesn't suffer from the C++ >> flaws that you mentioned. You will find all of the details here: >> >> http://www.inf.ethz.ch/personal/wirth/Articles/Oberon.html >> > > Although I see there is an ARM Oberon compiler, it's not really aimed at > embedded systems (it seems to have been targeted at the StrongARM > originally), and there certainly is nothing for other embedded devices. > It's an interesting language, however.
I've now adapted the Oberon-07 ARM compiler to specifically target the NXP LPC2000 family of ARM7 microcontrollers. For details see: http://www.cfbsoftware.com/armaide -- Chris Burrows CFB Software
David Brown wrote:
> In C, your header file might contain: > > extern void startMotor(void); > extern int motorSpeedTarget; > > And the C file contains: > > static void runMotor(void); > static int currentSpeed; > > > With C++, your header file has the class definition : > > class Motor { > public : > void start(void); > int speedTarget; > private: > void run(void); > int currentSpeed; > } > > > There is no excuse for designing an OO language in which code and data > that is explicitly reserved for private use within a class > implementation must be publicly exposed in the interface definition.
I would have never dreamed that I would some day be defending C++ ;-). I think you are comparing apples and oranges here. In the C version there is a single instance of Motor, whereas the C++ version lets you have multiple Motor instances. If the singleton instance is sufficient, then the C version is also a valid C++ implementation. The reason for the private part (as you probably know) is separate compilation. If code in another compilation unit needs to create an instance of Motor, it needs to know how much memory to allocate. In the traditional Unix style compilation model, the information needs to come from the specification (e.g. Motor.hh). If it is in the implementation part (e.g. Motor.cc), then you either need some kind of compilation library, or an additional whole-program compilation step before linking. -- Pertti
Pertti Kellomaki wrote:
> David Brown wrote: >> In C, your header file might contain: >> >> extern void startMotor(void); >> extern int motorSpeedTarget; >> >> And the C file contains: >> >> static void runMotor(void); >> static int currentSpeed; >> >> >> With C++, your header file has the class definition : >> >> class Motor { >> public : >> void start(void); >> int speedTarget; >> private: >> void run(void); >> int currentSpeed; >> } >> >> >> There is no excuse for designing an OO language in which code and data >> that is explicitly reserved for private use within a class >> implementation must be publicly exposed in the interface definition. > > I would have never dreamed that I would some day be defending C++ ;-). > > I think you are comparing apples and oranges here. In the C version > there is a single instance of Motor, whereas the C++ version lets > you have multiple Motor instances. If the singleton instance is > sufficient, then the C version is also a valid C++ implementation. >
I realise there is a difference here, but I think the comparison is still valid for two reasons. One is that you very often have a single instance, but in C++ you wrap that instance in a class for which there is only a single staticly-allocated instance. So even if you only have a single motor in the system, the natural C++ implementation would have a motor class in this way. Secondly, if you have multiple instances of "motor", then the natural C implementation would be to have a struct for private data, and a series of functions that take a pointer to that struct (or an index into an array of such structs, depending on which is more efficient on the target). If you have a lot of publicly accessible data, you may define the struct in the header, or you may split it into two structs - a public struct in the header, and a private struct in the implementation (that makes more sense using an array index rather than a pointer parameter). Either way, you at least are still separating your public functions (included in the header) and private functions (in the implementation file only). Yes, C code is valid C++ code - but if it is C code, it's not a C++ program.
> The reason for the private part (as you probably know) is separate > compilation. If code in another compilation unit needs to create > an instance of Motor, it needs to know how much memory to allocate. > In the traditional Unix style compilation model, the information > needs to come from the specification (e.g. Motor.hh). If it is > in the implementation part (e.g. Motor.cc), then you either need > some kind of compilation library, or an additional whole-program > compilation step before linking.
I know the reason for including the private part - it's still very bad design. It's based on a compilation and link strategy that was aimed at the limited computers of 30 years ago, and is simply not appropriate for a language of C++'s date. There were already better models in use at that time (such as Modula 2) - C++ should have been better than existing models, not worse than the reigning king of bad models (C). This stuff is not rocket science now, and it was not rocket science when C++ was conceived - even if you don't want the full whole-program compilation process (because of long build times). C++ was created by tagging OO onto C without doing anything about the design limitations and problems of C, and the result is a language that is not nearly as good as it could have been.

Memfault Beyond the Launch