C++ in embedded systems

This depends on what your definition of "functional" is. Most people hold it to be first class functions and some include higher order functions. Immutable data structures are not strictly necessary - every recognized functional language allows destructive update in some form.

C has first class functions (via function pointers) and C++ inherited that from C. That makes functional programming possible if not necessarily easy.

You are correct that it is not recognized ... it is there nonetheless.

You have a different definition of "support". By my definition, "support" for something in a language means that something can be accomplished within the scope of the language's syntax and semantics. To that end, assembler supports all possible paradigms - BASIC, for example, does not.

I believe C++ was designed to add OO concepts to a procedural base language. Clearly it was not designed to *be* OO because objects are not central to coding nor even necessary. Writing purely OO code is impossible in C++ because object support does not extend to the basic data types. However, writing purely procedural code is easy.

C++'s support for generics is no more than a kludge - a compiler trick. True generics allow functions to be written without regard to data types. That is impossible in C++. Templates allow code to be more easily "specialized" for a particular concrete type but they are a far cry from generics.

I mean design.

All the paradigms we are discussing are thought exercises. OO centers on abstracting the "world" in terms of actors and actions they perform. Functional and procedural models center on actions and the objects to be acted on. These models are not orthagonal, they are two sides of the same coin.

I believe good designers bounce back and forth between these modes of thinking constantly. Our thought processes naturally deconstruct problems in a certain way ... some problems are more actor oriented and some are more action oriented. Procedural thinking makes solving an actor oriented problem clumsy - OO thinking does the same for an action oriented problem.

Implementation issues are secondary to the thought process. Any Turing complete language can simulate any other (with varying degrees of effort). The extent to which any particular language helps in implementing the program model is relevent only to expediency. As all program solutions involve some aspects from each of the models, the choice of implementation language is less critical than the solution itself.

I firmly believe the language wars arise, in part, because programmers forget that their chosen language facilitates a model of thinking that they find comfortable, and it is not the language they are defending but their model of thinking.

My response is: you absolutely CAN do this in C. Full C++ inheritence is possible in C as evidenced by the first C++ compilers which compiled C++ code into C. The result is very messy and, IMO, unmaintainable, but it clearly demonstrates that C, in and of itself, does support OO (at least to the same degree that C++ does).

How is it a "mistake" to be ignorant of the cost of using a feature? Particularly when the cost is either not known or not advertised. As I said before, most of these issues were found by frustrated developers looking at the compiler's output. The documentation for your compiler rarely tells the gory details of the implementation of language forms.

People who write code for GHz processors with virtual memory and RAM to burn largely don't care about the overall efficiency of their compiler or the relative efficiency of language forms (they may pay it lip service, but in the end it doesn't affect their ability to write the program). I'm reading this thread in comp.arch.embedded where most programmers do care.

George

Reply to
George Neuner
Loading thread data ...

Best post in this thread yet, IMO.

Steve

formatting link
formatting link

Reply to
steve at fivetrees

"Andras Tantos" wrote in news:zeN%a.5314$ snipped-for-privacy@nwrddc01.gnilink.net:

I'll note in passing that Analog Devices VisualDSP family includes an inter-module post-processor. This is an optimizer invoked by the linker and can selectively re-compile modules with new options to optimize the link.

The linker also includes a feature to strip unused objects (functions, data items). You pass it a root object (typically main) and an exclusion list (eg. symbols in startup code) and it constructs a tree of used objects and tosses out anything not in the tree. This eliminates the need to put every function in a library in a separate file.

--
Kenneth Porter
http://www.sewingwitch.com/ken/
Reply to
Kenneth Porter

I was not aware that VC had whole program compilation (or anything like it). It has so-called "global" optimization of data access and function calls, but the optimizations are strictly intra module AFAIK.

In any event, given that the call to virtual func() in "call1" is indirect, I (currently) don't expect the compiler to be able to do a great deal with it - the inferencing necessary to do so just hasn't made it into the compilers yet.

"Call2" is a different matter, however. You presented a very good discussion of how the BE, given a fully typed IL might optimize the call to func() in "call2". But in concentrating on the BE you forgot the simplest way of all.

The FE knows the object is always "A" and it also knows the name (label) of A's func() method which it puts into the vtable for address resolution by the BE. The FE does not need to code an indirect access through the vtable - it can invoke the method directly by label (remember the first parameter to a non static class method is always a pointer to the invoking object). This leaves the BE simply to resolve the function address.

What would you do with *all* possible combinations? No, I think the compiler needs only to generate the exact typed overloads asked for in the code and possibly a default to go to when the runtime types don't match any of the overloads. Or just do nothing (like a switch with no default) ... this is C++ after all 8-)

Yes it requires RTTI, but the lookup would involve only one vtable access per object parameter and then a table match.

It's probably something they just didn't consider. The parameter conversion rules require that an object parameter must be converted to the "best fit" object with the single stipulation that no intermediate temporary object be created. It does not define "best fit" nor does it specify that objects passed by pointer are to be converted using the static type of the pointer.

After a careful reading of the document, I don't see anything which specifically prohibits a runtime resolution scheme nor do I see any prohibition of the parameter conversion: [base class] pointer to runtime object. No example is given for this particular case so I can only go by the explanatory text.

Anyway, nobody implement this currently and nobody will because it would break existing programs. Therefore it is all academic until the next standard revision 8-)

George

Reply to
George Neuner

My definition of "first class functions" requires that the user be able to create new functions at run time. I can't see any reasonable way to accomplish this in C using the supplied pointers to (const) functions. If you know of a way to do it, can you please share it with me?

Kelly

Reply to
Kelly Hall

Stroustrup mentions the 'problem' of template code bloat in his introductionary chapter on templates when he is explaining user defined specialization. He then goes on to develop a example of how to avoid it. Meyers mentions the 'problem' in item 42 of "Effective C++" and gives a solution too. These are perhaps the two most read C++ books around. On top of that the 'issue' is also mentioned again and again in language wars when advocates of other languages compare their language against C++. So this behavior is hardly unknown or unadvertized.

The default template behavior is optimized for speed and you want it optimized for size. Maybe implementers will provide templates with this default behavior when C++ gets popular in the embedded world until then just roll your own.

--
Rob
Reply to
Robert Jan Schaper

All of them were very enlightening, even those aparently controversial.

Regards.

Elder.

Reply to
ih8sp4m

snipped-for-privacy@visi.com (Grant Edwards) wrote in news:3f3bc814$0$153$ snipped-for-privacy@newsreader.visi.com:

Which, in essence, is exactly what I said in the paragraph preceding the one you quoted, and which you conveniently snipped.

MV

--
Do not send e-mail to the above address. I do not read e-mail sent there.
Reply to
Martin Vuille

snipped-for-privacy@aol.com (Dingo) wrote in news: snipped-for-privacy@posting.google.com:

Personally, I subscribe to the view that EC++ was concocted by compiler vendors in order to create a market for their non-Standard- compliant C++ compilers.

I find many aspects of the rationale downright insulting, making direct or indirect references to embedded system developers' supposed limited ability to comprehend C++.

The removal of templates, exceptions, and RTTI is arguably justified on the grounds of efficiency although, as has been pointed-out elsewhere in this thread, any half-decent C++ compiler will allow the user to disable those anyway.

On the other hand, perhaps someone can explain why "mutable", namespaces, and the C++-style casts were removed, if not to make the compiler- writers' lives easier.

MV

--
Do not send e-mail to the above address. I do not read e-mail sent there.
Reply to
Martin Vuille

moment.

far

can

The global optimizaer is global for the module as you said, and is part of almost all current compilers. Link-time code-generation (VC term) is another thing and is part of VC since 7.0, I think. It's definitely part of 7.1.

In theory yes. In practice, I haven't heard of anyone doing such things in the FE. But maybe I'm wrong.

Regards, Andras Tantos

Reply to
Andras Tantos

Ken Lee wrote: snip

Now I understand you, but the point is at best moot. Don't get me started on tools and Software Engineers.

We may be going round in circles here because I think it was I who expressed that sentiment.

THat's fine and exactly my point. The overall objective is to design a system which functions and performs correctly. OO is just one way this can be done but it is by no means the only one nor in my view the best one for embedded systems.

Ian

Reply to
Ian Bell

It's working now. Fascinating stuff. Just proves that a design is still only as good as the people doing it.

Ian

Reply to
Ian Bell

Agree 100%

Ian

Reply to
Ian Bell

Hi!

Yes it's academic. But I was interested so I've talked to a couple of people and flipped through the C++ standard and found this:

5.2.2 - Function call [expr.call] ....

-3- The type of the function call expression is the return type of the statically chosen function (i.e., ignoring the virtual keyword), even ^^^^^^^^^^^^^^^^^^^^^^^^^^ if the type of the function actually called is different. This type shall be a complete object type, a reference type or the type void.

From this I would conclude that overloaded function resolution happens at compile-time, statically.

Regards, Andras Tantos

Reply to
Andras Tantos

snipped-for-privacy@aol.com (Dingo) wrote

I happen to disagree; that line isn't clearly and cleanly drawn (or could be in general). That "rationale" is pretty old and concerns other than safety in embedded systems (such as the availability of in-house-built C++ compilers) influenced the decisions.

For a different and somewhat contrary view, have a look at the ISO C++ standards committees TR on peformance issues:

formatting link

- Bjarne Stroustrup,

formatting link

Reply to
Bjarne Stroustrup

Bill Pringlemeir wrote in news: snipped-for-privacy@sympatico.ca:

Yes, my point exactly; that's what I meant by "to make compiler- writers' lives easier." But that is not an argument invoked by the EC++ rationale.

There are many other things that could be removed from C++ that would have a much greater impact. What a coincidence that the things that were removed are largely things that were late additions to the C++ Standard and that therefore would have required extra effort to be supported by pre-Standard compilers.

I don't care if vendors want to subset C++ out of desire to sell their sub-Standard compilers to developers. I _do_ care when they spread FUD about C++ in order to do it. These deletions in no way make EC++ better able to "fulfill the particular requirements of embedded systems designs" than full C++.

"mutable" is also indispensible in certain circumstances to allow for const objects, and const objects are very useful in leveraging the C++ type system to assist in making code more reliable.

static_cast, const_cast, and reinterpret_cast have nothing to do with RTTI. Only dynamic_cast is related to RTTI.

On the other hand, static_cast and const_cast do make a program more reliable and more maintainable by working within the compiler's type system, instead of bypassing it, as C-style casts do.

Both C and C++ define numerous different symbol scopes, so I have a really hard time believing that namespaces will slow anything down significantly.

Visual C++, for one, allowed this long before EC++ came along, and I'm sure that others did too.

How does EC++ make this easier than a simple line of text in the description of the library that would state "does not use exceptions or templates"?

MV

--
Do not send e-mail to the above address. I do not read e-mail sent there.
Reply to
Martin Vuille

Hi Kelly,

My understanding of "first-class" is that a first class item can be passed as a parameter, returned from a function and stored in a data structure. I've never heard that dynamic creation was a necessary component.

No, C/C++ can't create functions but using function pointers you can construct dynamic chainings of functions. I wouldn't call it "composition" (or anything close) but it suffices for a lot of uses.

George

Reply to
George Neuner

Bill Pringlemeir wrote in news: snipped-for-privacy@sympatico.ca:

Namespaces are just a formal way of specifying how to decorate 3rd party API's with a vendor's name to avoid collisions. Removing them causes additional code clutter as one is forced to decorate every point of usage (eg. "vendor27_do_something()"). (With namespaces, one uses a using statement at the top of a block to identify which vendor's API's are in force for that block.)

If you use no 3rd party code (including libraries developed by other teams within your organization), namespaces are admittedly superfluous.

--
Kenneth Porter
http://www.sewingwitch.com/ken/
Reply to
Kenneth Porter

Google found this:

formatting link
that lists the following conditions for "first class"-ness a) named by a variable b) passed as an argument c) returned as a result d) stored in a data structure e) created in any context

C has problems enough with arrays and structures let alone functions. In general, C forces one to be satisfied with pointers to non-trivial data instead of the data itself. Since I've been drinking the C Kool-Aid for years now I understand that slinging pointers around is both what has to happen deep down anyway on most CPUs and also enhances efficiency. I've been happy to keep arrays of function pointers to use as the basis for my state machines. It's just that C's support for functions is a whole lot less featureful than almost any functional programming language.

The last item describes being able to create new functions within the scope of another. Pascal and its ilk do that quite nicely while C/C++ limits you to global or file scoping.

My attitude is that "sufficing for a lot of uses" lies somewhere down the feature hierarchy from "first class". I'm happy that C provides as much as it does (it beats Fortran all to hell) but it still lacks the features I enjoy from the functional language realm (ML, Haskell, Scheme).

Kelly

Reply to
Kelly Hall

My education is obviously dated. I took CS with Mitch Wand (EOPL) and Rick Kelsey but it was more than a few years ago. I don't recall that creation context mattered - what was important ws that that the whatsit be able to be passed around freely.

Nice to see Wellesley is teaching CS with Scheme instead of the language du jour.

No argument there 8-)

True, but Pascal's nested functions have limited visibility - they are not unlimited scope closures in the sense of Scheme et al.

Yeah, the only reason I care a wit about C++ is for business. For my own programming I wouldn't care if I never saw it again.

George

Reply to
George Neuner

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.