GCC support for C++

Go To Last Post
88 posts / 0 new

Pages

Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How well does GCC support C++ for the attiny85 as I am looking at converting over to C++?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This link will give some information on AVR GCC C++: http://www.nongnu.org/avr-libc/u...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

C++ in an ATtiny? Kinda like using a Caterpillar D7 to dig a hole in a flower pot, isn't it?

Keep in mind that there are very few resources in an ATtiny, especially SRAM. You can blow through 512 bytes pretty fast, especially if you do much dynamic allocation of objects and use lots of classes.

Don't get me wrong, I happen to like C++. Even so, as my metaphor above shows, I also believe in using the right tool for the job. C++ in an ATmega2560 - sure! In an ATtiny85 -- I wouldn't.

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is no penalty to using C++ over C when used properly. So if you're willing to use C on the ATtiny, then there is no reason not to use C++.

(it's a myth that C++ causes bloat)

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

glitch wrote:
There is no penalty to using C++ over C when used properly.
The key phrase here is "when used properly". I don't know how to use C++ "properly" on an ATtiny. Perhaps you could write a tutorial to teach us? :wink: A list of topics I've gleaned from other posts:

- Writing your own "new"

- Allocating static objects in flash

- Exceptions: Just Say No

- Large virtual function tables, dynamic allocation of objects, and tiny memories.

- The STL and your ATtiny - why "free" code isn't free.

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

(Paraphrasing Lee) "I'll bite, Stu":

Quote:

C++ in an ATtiny? Kinda like using a Caterpillar D7 to dig a hole in a flower pot, isn't it?

If you (as you yourself admit) do not know what to use and what to not use in C++ when programming for microcontrollers, from where comes this certainty that it is a Caterpillar in a flower pot?

Quote:

especially if you [...] use lots of classes

This points to a huge misconception. Could you tell me how much you loose using classes (many or few, don't care) compare with not using classes, given that you do not use virtual functions? (Hint, the "this-pointer").

BTW, while you're at it, I'd like to have some hint about the cost of actually using virtual functions (some indication of the space used for the v-table data-structure, and what the indirections during the call would be).

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kewl! We have at least two C++ experts on the AVR! Where's the tutorial? :twisted:

As for the huge number of classes, I had intended to say with virtual functions. Sorry, I tend to assume that use of lots of classes implies virtual functions, since that's where (I consider) the power of C++ shows up. Obviously you don't need to use virtual functions and without them the v-tables are downright frugal. Without virtual functions, object size is now limited to the member data and the single indirect v-table of reasonable size. You are then limited only by the size of the ATtiny, just as you would be in straight C.

On the other hand, you didn't respond to the questions about exceptions, redefining the new operator, static allocation of objects in flash, etc.

Oh, and BTW, everything I've seen from Joerg and Eric suggest that C++ is not "officially" supported on the AVR, although that may be my interpretation, not fact.

Where's the tutorial?

Stu

Edit 1: I seem to recall a thread on allocation of the vtable to flash. That would go a long way to ameliorating any heap usage of objects, since I believe the vtables for any class would be static, wouldn't it?

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

TheOtherLeft wrote:
How well does GCC support C++ for the attiny85 as I am looking at converting over to C++?
I recall an unexpected linker error when compiling my C++ code, something *PURE_VIRTUAL*. I don't have the code handy at the moment, but just defined it somewhere to satisfy the linker. Should've investigated it further, but it worked; obviously could impact designs utilizing some types of inheritance.
stu_san wrote:
The key phrase here is "when used properly".
I can think of no better way to determine what is (and isn't) "proper" than by trying it and seeing what obstacles arise.

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

stu_san wrote:
As for the huge number of classes, I had intended to say with virtual functions. Sorry, I tend to assume that use of lots of classes implies virtual functions, since that's where (I consider) the power of C++ shows up. Obviously you don't need to use virtual functions and without them the v-tables are downright frugal. Without virtual functions, object size is now limited to the member data and the single indirect v-table of reasonable size. You are then limited only by the size of the ATtiny, just as you would be in straight C.

Indeed virtual functions are a powerful feature, however they come at a cost. There is still a lot of power in encapsulation, and the other paridigm differencees that c++ brings to the table. So while it may not be any better than using pure C, my point is that it's not any worse either.

stu_san wrote:

Oh, and BTW, everything I've seen from Joerg and Eric suggest that C++ is not "officially" supported on the AVR, although that may be my interpretation, not fact.

Yes, it's my understanding that the GCC C++ implementation for AVR still has some holes. My comments were general C++ comments, not specific to GCC/AVR support of it.

stu_san wrote:

Kewl! We have at least two C++ experts on the AVR! Where's the tutorial? :twisted:

Sorry, no tutorial, I'm no "expert".. perhaps someday. As I said, my comments were general in nature, only to disband the myth that C++ instantly adds bloat to the application.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The C++ compiler is available for the AVR. However there are caveats in using it, and I'm sure there are undiscovered issues. I know that the list of known GCC bugs also covers some C++ bugs for the AVR. Joerg and I generally don't look at the C++ issues as neither of us have enough knowledge in the matter. Also because there are still bugs in the C toolchain that need to get fixed. We certainly welcome more help in the C++ area.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

stu_san wrote:
I seem to recall a thread on allocation of the vtable to flash. That would go a long way to ameliorating any heap usage of objects, since I believe the vtables for any class would be static, wouldn't it?
Yes, the vtables for a class would be static. I don't know if they are store in flash or sram. Since you use the term "ameliorate", I assume that you are aware each object of a class with a virtual method must contain a pointer to the vtable of its class.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

These got rid of the link errors. When you need these, what they are for? Haven't had time to look into it.

extern "C" void __cxa_pure_virtual();
extern "C" void __cxa_guard_acquire();
extern "C" void __cxa_guard_release();

void __cxa_pure_virtual()
{
   abort();
}

void __cxa_guard_acquire()
{
}

void __cxa_guard_release()
{
}

Use malloc/free inside the news and deletes. Do a search, we've seen this posted several times.

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You should become a politician, Stu :wink: You are dodging the burden of proof for the Caterpillar by asking for a tutorial...

What did I react to? This: A sweeping allegation that there is a heavy run-time performance penalty for using C++ in embedded systems, backed by no facts whatsoever.

Re the tutorial, I am not planning on writing any such thing - at last not right now (see footnote though). If I was to write it, it might go something like this (sketch):

Getting C++ to work (ie. getting the compiler up).

OO programming basically stands on the tiers: Encapsulation, Inheritance and Polymorphism. You don't need to use all three tiers, but if you do you should be aware of the costs.

ENCAPSULATION is inheretly good. It helps depict things in a natural way. You ask objectys to operate rather than call functions to manipulate data. Encapsulation will also help you avoid name clashes (as every class is a namespace). This argument is a lot about source code quality and source code eficciency (in the sense that you can maintain well written source code more efficiently).

There is very little run-time performance penalty for using encapsulation. [A few experiments with the "this"-pointer are needed here]. Function calls are resolved at link time, just as in C - there is no overhead for the call per se compared to plain old C.

[Maybe a section here about "all static classes". It would go something like this:
Using classes generally means that you define a class and then instantiate several objects. What if you want to encapsulate eg a piece of hardware that actually only exists in one instance (eg. the ADC)? One elaborate solution is to use a design pattern called Singleton, but then you'd have to pay the penalty of dynamic memory allocation. One alternative is to make all methods of the class static, and then be cautious to not create several object instances of this class]

INHERITANCE: Just as with encapsulation there is no inherent penalty using inheritance compared with plain old C. Apart from the obvious use of inheritance to model specialization/generalization, there is one very interesting use of this in C++ - specifying interfaces.
[Specifying interfaces means creating pure virtual classes, which in turn generates v-table entries, and indirections at call time. the cost in space and time would need to be investigated]

POLYMORPHISM: This implies virtual functions, which in turn generates v-tables... [see above].

Having dealts with the three tiers, we need to cover some other stuff too:

DYNAMIC MEMORY ALLOCATION: An explanation of the costs involved, and why dynamic memory allocation is not always a good idea. Not C++ specific at all, but would still be needed in such a tutorial.

THE COPY CONSTRUCTOR: An explanation of what the copy constructor is, and why we want to avoid activating it. Hide it, and pass objects as reference parameters.

[There was a lot more in my brain whan I started typing but it got lost. I'll come back and edit when recall occurs].

[EDIT]Added: An investigation on any memory penalties regarding the startup code when using C++.[/EDIT]

So Stu, with that embryo for a tutorial done, would you please give at least a hint about your Caterpillar reasoning? 8)

[footnote: Strange coincidence - just the other day I got involved in things pertaining to "C++ on embedded systems" at work, and just the type of questions we are discussing. Spooky. So no tutorial "right now", but who knows...]

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Johan wrote:
So Stu, with that embryo for a tutorial done, would you please give at least a hint about your Caterpillar reasoning? 8)
I suppose my reasoning was flawed by attributing an experience level to the OP. Also, I wasn't positing a run-time penalty as much as a code space penalty, again likely incorrect.

The problem as I saw it when I made the comment (and I'm sorry it pushed your buttons, Johan) was an assumption of what the OP was assuming would be available to him. As I say below, my initial reaction to C++ code is, "That's needlessly complex and out of touch with the hardware running it." It's unfair, and I know it. My bad.

To be honest and fair, there's no reason why C++ in all its glory should not be available, other than AVR gcc is a volunteer project and no one (myself included) has volunteered to make it complete. That's not a slam on the hard-working supporters of our current toolset (Joerg, Dmitry, Eric, et. al.) but on people like me who should at least contribute something. Mea Culpa.

In fact, C++ is not any harder than straight C in an ATtiny. On the other hand, it's not necessarily any easier. The same issues confront the designer, and I was wrong for implying any different.

As Bjarne Stroustrup himself has said:

Quote:
I never saw a project for which C was better than C++ for any reason but the lack of a good C++ compiler.
(http://www.research.att.com/~bs/...)

I guess in my mind, C is a small screwdriver while C++ is a power screwdriver - both drive screws into walls, but it's sometimes easier to strip the screw with the power tool.

Another problem I have is that I have dealt with programmers who literally do not want to know about the hardware they're running on. In an embedded environment especially, I believe that attitude to be dangerous and, ultimately, self-defeating. Since those programmers were great advocates of C++ as well, they (unfairly) were linked in my mind. Ehh, what should I be worried about -- they're probably on to Ruby or Python or whatever the next Language To End All Languages(tm) is. :twisted:

In conclusion, I apologize to those who took offense at my desire for a quick humorous phrase (a personality flaw, I admit, along with being long-winded). On the other hand, right now, the answer to "What is GCC support for C++ on AVR" is "well... it's like this..."

Oh, and thanks for the tutorial outline, Johan. Food for thought...

Stu

Edit 1: Stu's Observation On Computer Languages: As long as there are CS Grad Students, there will be new computer languages.

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

stu_san wrote:
I guess in my mind, C is a small screwdriver while C++ is a power screwdriver - both drive screws into walls, but it's sometimes easier to strip the screw with the power tool.
Considering resource utilization alone, I think your metaphor applies as one moves along the axis of increasing levels of language abstraction.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I guess in my mind, C is a small screwdriver while C++ is a power screwdriver

C: http://www.toolsforworkingwood.c... "These marking knives are both elegant and functional".

C++: http://www.joshspear.com/item/gi... "It is the biggest mofo of a Swiss Army Knife ever invented, ..."

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
http://www.joshspear.com/item/gi... "It is the biggest mofo of a Swiss Army Knife ever invented, ..."
"So, is that a giant Swiss Army Knife in your pocket, or are you just happy to see me?" :D :twisted:

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is a challange for the C++-evangelists.

Quote:
"I never saw a project for which C was better than C++ for any reason but the lack of a good C++ compiler."

Is avr-gcc in reality the type of C++-compiler that actually is better than C on a real target?
Or will the evangelist not even a come up with a working C++ example?

class complex
{ 
	public:
	int im;
	int re;
	complex add(complex a, complex b);
}
complex complex::add(complex a, complex b);

struct complex
{
	int re;
	int im;
};

complex add(complex a, complex b);

Rules of engagement:
Implement the add method and add function.
Initialise a and b, calculate c = (a + b) from main (one project using C and the other C++).
Both projects shall compile on the same optimisation level on the highest warninglevel without warnings.

Output: resulting size of BSS, TEXT and DATA and segments for the two projects and two working projects with linker scripts, make files and source.
Note:
The code may not be optimised away by the compiler some meaningful code must be generated.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Surely the optimiser will always optimise a menaingless piece of code like c=(a+b) unless either (a) 'c' is volatile or (b) 'c' is subsequently used somewhere (probably being written out to a 'volatile' PORT or something)

This is the problem with test code like this - far better to set a test like "flash a 1Hz LED" or something (ie the "real" kind of work that microcontrollers actually get used for)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

oloftangrot wrote:
Here is a challange for the C++-evangelists.
Quote:
"I never saw a project for which C was better than C++ for any reason but the lack of a good C++ compiler."

Is avr-gcc in reality the type of C++-compiler that actually is better than C on a real target?
Or will the evangelist not even a come up with a working C++ example?
Given the relationship between C and C++, the quotation is nearly a tautology. A counterexample would be something useful (use prototypes, folks) that C can do and C++ cannot do as well.

A reason for not using C++ would be the expertise of one's programmers.

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Or will the evangelist not even a come up with a working C++ example?

I might, in due time. (As has been hinted at in my "New toy!"-thread in the OT forum I might become involved in some work re exactly this topic. Unfortunately for this community this work will be baset on the TI MSP430 microcontroller, but if I find the time I might just do some parallell AVR experiments.)

Still, you're not aiming at the dead center of my point. Your argument seems to be very similar to the classic "compiler wars", where a certain piece of code shall be compiled with the contending compilers to show which one is best.

I hope that I have argued two points above:

My first point is that you can use C++ to get good quality code, where "quality" definitively is not restricted to fastest and/or smallest generated code. In my opinion (and experience) there are other aspects of code quality, eg. clearness (as in "easy to use in a code inspection or walkthrough"), readability (as in "stands a better chance of being maintained with reasonable cost" etc.

My second point is that there are a number of misconceptions as of the costs of using C++. One such misconception is goes something like "as soon as you write something in C++ there is a huge overhead due to the v-table things".

I certainly never had the intention to argue that C++ should be used "to the limit" (exploiting all C++ constructs), in all cases, for all problems etc. (I have not even argued that you must choose one or the other for a certain project. Last time I looked, and the umphteen times before that it was quite possible to mix C and C++ in one project, just as it is possible to mix C and assembler. The latter is being done - whats so strange about the former?

Some of the arguments here (and in other similar threads) remind me a lot of the usual arguments in discussions on C vs. assembler, and IMO those arguments often tend to be more or less ridicolous, eg. "black-and-white" arguments where you must choose one side and then stick to it no matter what. Please let's not do that here.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

While it is easy to play at C++, it isn't really easy to make the mental transition from C procedural methods to truly understating and fully exploiting the object oriented aspects of C++.

I don't think the issue should be 'is C smaller' but is it worth climbing the learning curve to really know what you are doing with C++ when you are writing relatively simple programs for small microcontrollers.

Learning C++ makes a lot of sense when you are are part of a team designing a set-top box using an ARM processor, but it is IMHO way overkill for using on an AVR for controlling a microwave oven. I agree with the Caterpillar D7 Bulldozer for a flowerpot analogy.

I would love to see that tutorial though.

Smiley

P.S. I believe that any idiot can (an many idiots do) write decent programs in C. But that it is much harder to write a 'decent' program in either Assembler or C++, both of which IMHO are far harder to use properly.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

smileymicros wrote:
But that it is much harder to write a 'decent' program in either Assembler or C++, both of which IMHO are far harder to use properly.
I agree with that statement, Smiley. Assembler being harder because it lacks signifcant power of abstraction so one has little guidance how to solve their problem. C++ being harder because it has significantly more abstractions than C which can lead to choosing a poor overall model or using constructs which are quite inefficient for the task.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kmr wrote:
C++ being harder because it has significantly more abstractions than C
C++ offers several tools for abstraction in addition to those of C. But is design by objects any more abstract than design by functions?

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Obviously you need to restrict the usage of the language capabilities (polymorphism, exceptions, dynamic casts...what more?) in order to use it for coding on a resource constraint target. Maybe a fair part of C++ remains, I don't know.

But I do know one thing. If not even the simplest example of a compiled program using a class will show up, nor will all those other examples where C++ might prove it self do.

My example was deliberately chosen not to "stress" the compiler in any way. It demonstrates encapsulation, which in its own is a nice feature. I strongly believe that the best way to put the bloating discussion to rest is to actually show a working example which for obvious reasons need to be comparable to C. And if the experts can't provide that example I might chose to reject all those other claims they make.

Olof

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

cpluscon wrote:
C++ offers several tools for abstraction in addition to those of C. But is design by objects any more abstract than design by functions?
If by "design" you mean the design of the finished product that is available for review. Then, yes, I think objects are more abstract than functions alone. As just a single "more abstract" example: the direct encoding of is-a relationships where the compiler automatically selects the proper function for polymorphic objects rather than having to keep functions updated selecting the proper function based on an objects type id.

If by "design" you mean the thinking of programmer during the writing of the program, then one can interpret that several ways. You can have a C++ programmer who knows the language and his compiler well. As he writes the C++ code, he is already visually the resulting assembly code. So, while his has tools of abstraction, he may be designing considering mostly the resulting assembly language. Whereas one can have a C programmer who doesn't even understand a data or return-call stack, doesn't know assembly language, and is thinking of his program only in C constructs. So, in their "design", one could argue the C++ programmer be designing at a lower level of abstraction than the C programmer while using language with greater amounts of abstraction.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, learning to think in objects can be a hard and not-so-fast process. At least it was (and still is) for me. I find this strange but interesting. When I act in "real life" many (most?) things are OO rather than functional.

Eg when I'm about to drive somewhere I do engine.Start() rather than Start(engine). There is no general procedure Start that can act on everything. The operation Start is one of the "aspects" of the engine. And the wipers. But certainly not the doors. They have an Open operation, which the wipers does not have. (The engine might have an Open operation but it is reserved for the mechanic..., and engine-opening is conceptually quite different from door-opening.)

So the question is, if "real life" things often are so naturally OO, why was/is it so hard for me to think like that when programming? In the end, what I manipulate in my programs are in the end "real world" things (lets leave the "We're all a computer simulation" thing out for now :wink: .)

Quote:

It demonstrates encapsulation, which in its own is a nice feature.

Agreed on the nice feature (understatement, if you ask me)!

On the "challenge application/example": One way to force the compiler to actually generate code without resorting to some strange trick would be to read the real and imaginary parts of the complex numbers from ports, and output the result to pins. No need to construct something that really would work, just read 2x2x2 bytes from PORTB for the real and imaginary parts of the two complex inputs, do the computation, and output 2x2 bytes for the result. This should force the compiler to actually generate code, right? (Or am I just in need of sleep?)

This now has become more tempting than I had planned. Might just let the MSP430 rest a while tomorrow, and try this out... No promises, though.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Fri. Dec 21, 2007 - 12:27 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
As he writes the C++ code, he is already visually the resulting assembly code. So, while his has tools of abstraction, he may be designing considering mostly the resulting assembly language. Whereas one can have a C programmer who doesn't even understand a data or return-call stack, doesn't know assembly language, and is thinking of his program only in C constructs. So, in their "design", one could argue the C++ programmer be designing at a lower level of abstraction than the C programmer while using language with greater amounts of abstraction.

I'm missing something here: What forces the C++ programmer to think more in/on the generated machine code than the C programmer?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Learning C++ makes a lot of sense when you are are part of a team

IMO, learning C++ (or maybe some other OO language) makes a lot of sense when you are working on your own. Roumor has it that you have been programming in C# - on your own... 8)

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Learning to do it "differently" is usually unpleasant, especially with age. After several years of religious adherence to top-down design, I read Meyer's classic on OOD and fell in love instantly (with OO not the author!). But I was about 23 years old.

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm not on either side here as I believe that the premise of 'better' is not absolute. There is a separation of arguments really...

1. does either C or C++ produce 'better' code? This could, notionally, be tested once you establish the metric(s) to be used (code size, speed of execution, etc) and an actual benchmark set of requirements (what is the code supposed to do). BUT this is not really possible because - there are many ways of coding anything other than trivial examples, the compiler has a myriad of options that may/not effect the result, there may be a dependency on the compiler used, and there are likely to be cases where using one language has advantages over the other an vice versa.

2. There are qualities to consider that go beyond the raw machine code/space-requirements. There are also all the quality attributes such as: testability, maintainability, reusability, extensibility, portability, etc. These, like space/speed, are things that have to be traded-off.

3. The tool is only really as 'good' as the person wielding it. It is probably fair to say that a 'good' programmer in either language will produce better results than a poor programmer in the other.

Personally, I select the tools in my kitbag that "I think" fit the job at hand, which might not be the same selection as someone else. It is a reflection of my own skill with each, my experience, and any outside constraints placed on me (back to those quality attributes... e.g. if you want something quick then you are likely to get it coded in the language with which I am most familiar).

So, I'm firmly rooted bang in the 'third way'... horses for courses :)

As for the learning curve for OO. Yes it is likely to be steep - if you have been taught procedural programming first! When OO first came into vogue I knew that if I started with C++ all I'd produce would be C with classes (look at the early MS foray into C++... lots of classes that were basically just glorified structures). To avoid this I learned smalltalk first there was no way of me slipping back to my familiar C practices.

P.S. The first language I learned to programme in was an assembler for an olivetti machine that probably had less processing power than the calculators that they now give away in boxes of cereal :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
I'm missing something here: What forces the C++ programmer to think more in/on the generated machine code than the C programmer?
Absolutely nothing. The question I answered had an ambiguity I discussed. As part of that discussion, I elborated that term "design" could be related to considering the low-level consequences of one's program rather than the higher level of abstraction afforded by the language.

Of course, one of the signs of abstraction is that the resulting assembly language looks less and less like the original source code. When I write a program in Perl, I have little idea about what machine instructions the program will be executing compared to programming in C.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The idea of software design is not all that ambiguous.

We are discussing the advantages of two relatively distinct design approaches, object oriented and procedural (top-down, structured, Yourdon, etc). Again, I question your assertion that design by objects is somehow more abstract and therefore more difficult to learn and use.

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

cpluscon wrote:
We are discussing the advantages of two relatively distinct design approaches, object oriented and procedural (top-down, structured, Yourdon, etc). Again, I question your assertion that design by objects is somehow more abstract and therefore more difficult to learn and use.
Quoting myself:
kmr wrote:
C++ being harder because it has significantly more abstractions than C which can lead to choosing a poor overall model or using constructs which are quite inefficient for the task
I didn't say the language is harder to learn -- though C++ does take longer to learn because there is more to learn than plain C. This goes well beyond objects, such as templates or large STL. Also, I didn't say it was harder to use.

Further explaining my statement in the context of your point is that with more abstractive power, one has more choices in design. Thus, it can lead to some poorer code than when one has a less expressive language (like C) where there is less choice to choose a construct. With a more abstract language, more things are handled for the programmer so one is further removed from the resultant binary. If one doesn't give careful thought, one can employ abstractions where the compiler generates fairly inefficient results (compared to optimal results). Whereas in a a less abstract language, when you have to do more of the work that an abstraction encapsulates, it would visible if you are choosing an inefficiency.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kmr wrote:
C++ being harder....
Since you weren't specific enough I had to assume you meant C++ is harder to use and/or harder to learn to use well. Otherwise, what did you mean by "harder"?
kmr wrote:
With a more abstract language
I'd say C++ is more expressive rather than more abstract.

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

cpluscon wrote:
kmr wrote:
C++ being harder....
Since you weren't specific enough I had to assume you meant C++ is harder to use and/or harder to learn to use well. Otherwise, what did you mean by "harder"?
The last part of that sentence:
kmr wrote:
...which can lead to choosing a poor overall model or using constructs which are quite inefficient for the task
The context statement of this is in response to Smiley's quote:
smileymicros wrote:
it is much harder to write a 'decent' program in either Assembler or C++, both of which IMHO are far harder to use properly.

cpluscon wrote:
I'd say C++ is more expressive rather than more abstract.
I believe we are using different definitions of "abstraction". I gather you are thinking of the typical English language use of the term whereas I'm using the term abstraction in the computer science sense: http://en.wikipedia.org/wiki/Abs...(computer_science) . In the CS sense, I'd consider expressiveness a consequence of abstraction.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I wrote:
what did you mean by "harder"?
Without quoting prior posts or Wikipedia can you explain how C++ is "harder"?
kmr wrote:
I believe we are using different definitions of "abstraction".
I was referring not to abstraction, but to your use of the word abstract:
kmr wrote:
With a more abstract language

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

cpluscon wrote:
Without quoting prior posts or Wikipedia can you explain how C++ is "harder"?
Sure. I wish I had with me my books "Effective C++" and "More Effictive C++" which together contain 85 tips on using C++. Before a specific case of where using C++ can easily go wrong in non-obvious ways, in general after reading those books, I found about a dozen things I was doing unsafely or inefficiently in C++ that was not at all obvious from using the language successfully for years. At that time, I was working on porting my Computed Tomography simulator ( http://www.ctsim.org ) from C to C++. About 1/2 of those dozen were inefficiencies a nd about 1/2 were issues that could lead to difficult to diagnose bugs. Now, one could argue I was a poor C++ programmer, but to my mind (and those of others), there are subtle areas of C++ where one can run into trouble using the language in what would seem a reasonable way.

Before the specifics, here's a few references to books on the subject of using C++ effectively. And again, many of these tips are non-obvious (as anyone would guess from the title word "Gotchas" below).

Effective C++: http://www.amazon.com/Effective-...

More Effective C++: http://www.amazon.com/More-Effec... (as if the first 50 tips weren't enough to cover the language!)

C++ Gotchas: http://www.informit.com/store/pr... ("C++ Gotchas is the professional programmer's guide to avoiding and correcting ninety-nine of the most common, destructive, and interesting C++ design and programming errors. It also serves as an inside look at the more subtle C++ features and programming techniques. This book discusses basic errors present in almost all C++ code, as well as complex mistakes in syntax, preprocessing, conversions, initialization, memory and resource management, polymorphism, class design, and hierarchy design.")

http://profcon.com/profcon/Gotch... ("Production C++ programming is complicated by numerous features of the language that behave or interact in unexpected ways - the Gotchas. Gotchas may cost programmers additional development time to track down obscure bugs, or result in superficially correct code that executes inefficiently. Gotchas appear in all parts of the language. ... Gotchas affect the correctness, efficiency and portability of C++ software.")

Below is a single example that may (or may not) cause an unexpected error -- this is beyond the unexpected inefficiences in my original claim. I present this as single example of where C++ is "harder".

This example is from http://www.linuxdevcenter.com/pu...

const SimpleString&
 examine_string(const SimpleString& input) {
//... maybe do some processing here ...
  return input;  //If "input" refers to a temporary 
                 //object, that object will be 
                 //destroyed as soon as this
                 //function returns.
}

On the surface, this seems like all a fine thing to do, but the above comments state the potential unexpected occurrance. The explanation for the above is: "The C++ compiler is allowed to create an unnamed temporary object for any const reference parameter. After all, you promise not to change the parameter when you declare it const. Unfortunately, the unnamed temporary goes out of scope as soon as control leaves the function, so if you return a const reference parameter by const reference, a dangling reference can result."

If you really want more specific examples, I can supply them once I get back to my references materials. (I haven't used C++ much in the last 5 years, so my memory of the specifics is not precise enough for posting).

Quote:
I was referring not to abstraction, but to your use of the word abstract:
kmr wrote:
With a more abstract language
I see. I thought my intent would be clear from the context of comparing languages with varying levels of abstraction. If I used the more specific phrase, "with a more abstractive language", perhaps a lot of quoting and requoting could have been avoided.

I don't want to give the impression that I don't like C++. In fact, I do -- quite a lot. For my Computed Tomography simulator, the port to C++ was a big win in terms of segmentation, maintainability, readability, and code reuse. I consider C a high-level assembler and C++ as an extension providing both more abstraction as well as the ability to still predict the emitted assembly code when one needs maximal performance. However, C++ needs to be more carefully used to avoid unexpected consequences.

Edit: Here's some CTSim screenshots: http://www.ctsim.org/screenshots

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks. Food for thought.

kmr wrote:
However, C++ needs to be more carefully used to avoid unexpected consequences.
I disagree but only with the word "more". (Since you don't say explicitly more than "what" I'll assume "more carefully than C".) Besides function pointers and the CPP as tools of obfuscation, the chaotic nature of procedural designs leads to deterioration as requirements and code change.

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, I'll bite.

The example given is as bad, wrong and dangerous as the C function:

char *examine_string( char *s) {
  if (s && *s) return s;
  return "Error";
}

And I've seen variations of this function a LOT.

I personally don't think that C++ is more difficult than C. The problem is that it isn't taught. Most people learn C and then they get a 2 day introduction into C++ and that's it. Koenig and Moo have shown that C++ can be learnt quite efficiently and easily (Accelerated C++) if you focus on C++, and not on C.

The books and websites from Meyers and Sutter are really good (highly recommended). But again, I'm not quite sure if they are appropriate. They focus mostly on advanced usage of C++, and if they were C books, they would have probably been called "Advanced C++ Tips & Tricks".

If the number of publications of what you should do and shouldn't do in a programming language is any indication about its dangerousness the world should have stopped programming in C in the early 80's.

C++ wasn't really designed to be an embedded programming language. I think that becomes quite clear when you look at the footprint of basic_string. I'm not even talking about the STL. But if you ignore the libraries for now and just look at the core language it offers enough features and advantages over C to justify its use on any processor (at least for me it does).

For me the difference between using C and C++ is like the difference in using hand-tools and power-tools (no pun intended). Most of the time I just want the job to get done and I use power tools. But every now and then there is a delicate piece and I need finer control over what is going on, so I revert to hand tools.

And by "reverting" I don't mean that in a bad sense. Granted, working with hand tools is less efficient (time wise), but that is not as important as precision in these cases (think critical timing).

I think this is where most of the "code bloat" in C++ comes from (and don't kid yourself, it exists). It's not that the language produces bloated code, it's the programmer who adds more features because it is so much simpler. In C you might think "no, I would have to add this function, write that one for this structure ... I don't think I'll need it that desparately", whereas in C++ it might be "hey, if I make that one a template I can do that too". Quite simple, isn't it, but you've just doubled your code base of that functional unit.

Markus

Edit: put code into code format and made sample more meaningful

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In (almost) every holy war on C++ versus C, on embedded systems, I never see mentioned EC++

If C++ could be used that easy on embedded targets, you should inform the ISO SC22/WG21 committee they're totally wrong.
Likewise, tell firms like IAR and Green Hills that their EC++ compliance is useless, and they wasted a lot of money. :P

~ Lou

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

cpluscon wrote:
Besides function pointers and the CPP as tools of obfuscation, the chaotic nature of procedural designs leads to deterioration as requirements and code change.
I agree that C has its significant limitations, including those your pointed out. As we all know, with C it's quite easy to create invalid pointers and memory leaks.

Still, my opinion is that such issues with C are more clear when writing or reading C sources compared with C++ where issues exist that would only be known by having knowledge of subtle aspects of the specification and which appear surprising to many when analyzing the source code.

My previous example was not arcane. Wow, passing a constant reference of an object sounds great and safe, taking advantage of C++ features. No worries about pointers dereferencing and "safer" because the object is const. However, many functions like to pass their input argument as their output argument to chain calls [like foo(input_for_both).bar()]. So, many people would think it'd be safe for a function to return the same const reference of an object that the function received. According to the C++ specification, that may or not return a dangling pointer. So what seems ordinary and safe and C++ double-plus good is truly an potential error that may show up at any time.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'd be surprised if a feature-disabled language ever really takes off. Generally, adding features is good, taking away features is annoying. EC++ probably looked good on paper, but ultimately the answer is probably, no thanks. (For me anyways.)

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kmr wrote:
My previous example was not arcane.
The example is a nit pick, pointing out an obscure anomaly such as those always found in programming languages. You seem to be thereby ignoring the larger more significant issue of software design, by which I mean the principles guiding the structure of elements that comprise the solution.

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

cpluscon wrote:
The example is a nit pick, pointing out an obscure anomaly such as those always found in programming languages. You seem to be thereby ignoring the larger more significant issue of software design, by which I mean the principles guiding the structure of elements that comprise the solution.
Yes, it is a nitpik, but becomes siginificant if you spend days trying to figure this out. Also, it is part of pattern of non-perspicuous of potential errors in otherwise innocent appearing C++ code.

And, yes, I have been ignoring the very important issue you mentioned. While I could easy make many posts about the positive points of C++ and the wins it has over C, that discussion is really outside the point of my reply to Smiley's comment.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
On the "challenge application/example": One way to force the compiler to actually generate code without resorting to some strange trick would be to read the real and imaginary parts of the complex numbers from ports, and output the result to pins.

I had hoped that declaring c as volatile or static both in the C and C++ example would result in working code. And if this would not work it was why I chose to declare the attributes as public (thus violating ecapsulation). This way it would be easy to access them without the need for accessor methods. Which might punish C++ unfair in the simple example. The problem of initialising a and b is also solved here.

I have been thinking about the add method prototype.

complex& complex::add(complex&)

might have been more fair to C++. If anyone cares to try to meet the challange feel free to try that instead.

Anyway the challange is not really about C++ vs. C in general. It's about the compiler maturity regarding C++ in avr-gcc.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I had hoped that declaring c as volatile or static both in the C and C++ example would result in working code.

Probably, but then we are changing the environments in the test, maybe "moving away from the realistic".

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

smileymicros wrote:
But that it is much harder to write a 'decent' program in either Assembler or C++, both of which IMHO are far harder to use properly.
kmr wrote:
I agree with that statement, Smiley. .... C++ being harder because....
kmr wrote:
Also, I didn't say it was harder to use.
kmr wrote:
C++...can lead to choosing a poor overall model
So your argument went from "poor models" to presenting pitfalls of passing by reference (which BTW is a relatively mundane feature of C++). The conflict between C and C++ is procedural design versus object oriented design. Period. The latter is more concrete IMO, not abstract, and therefore more intuitive and easier to use.

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

cpluscon wrote:
So your argument went from "poor models" to presenting pitfalls of passing by reference (which BTW is a relatively mundane feature of C++). The conflict between C and C++ is procedural design versus object oriented design. Period. The latter is more concrete IMO, not abstract, and therefore more intuitive and easier to use.
Yes, my initial point was poor models and unexpected inefficencies. When you focused on what was "harder", yes, I did shift to unexpected consequences. (BTW, the fact tht references are mundane (ie, ordinary and thus common) is the reason the potential problem has as a higher rish of being coded versus an arcane construct).

But, if you want to take this back to the beginning, very well. Yes, object oriented design is more abstractive -- that was my initial point. I realize my point was misunderstood because I used the word abstract rather than abstractive. I stand by my initial intent, though. Greater levels of abstraction can lead to unexpective inefficiences and choice of a poor model. The first because your source code is further removed from the resulting binary and it's easier to choose a construct that will use more machine cycles than optimal whereas in a language of lower abstraction you'd have to explicit code all those cycles. That'd give you a hint there could be a more efficient method when you realize you're writing hundreds of lines of code for something that should be simpler. That's similiar to clinical medicine. If you write a medication order and the nurse has to draw up 10 ampules of a medication, that's a simple (however non-precise and not always accurate) sign you chose the wrong medicine or dose. As for the second point, simply when you have a greater number of abstractions to choose from, you have a greater chance of choosing a less than optimal abstraction then when you have less abstractions to choose from.

I realize you are pointing our advantages of C++. You're preaching to the choir. As I mentioned I like C++ very much and its object oriented paradigm can be highly effective. If you search for threads on AVRFreaks you'll see where I was stating the improvements of C++ over C, even for embedded applications. It's not being schizophrenic, but examining the multiple issues from multiple perspectives.

Personally, my favorite programming language (and the large majority of my open-source source code) is in ANSI Common Lisp which transcends object-oriented programming into what is collectively termed the "metaobject protocol" -- a much higher level of abstraction than the simple object-oriented nature of languages like C++ and Java.

Despite the great advantages of abstractiveness, as one person wrote metaphorically earlier in this thread, "it's sometimes easier to strip the screw with the power tool." This is more true in the context of coding for microcontrollers with scare resources than for systems with more cpu speed and system storage. And, that was the whole context for this thread.

Edit:
1. By concrete, I assume you mean that the programming construct more closely resembles a physical object. Yes, I agree. That "concreteness" comes from the abstraction that C++ provides. Indeed, that's usual basic introdution into object-oriented programming. The elementry text starts with some simple physical object like "vehicle" which is subclassed into "4-wheel motorized vehicle" and splits into "car" and "truck" subclasses.

2. As examples of trying to choose the best abstraction: the choice of subclassing an object versus adding attributes to an subclass versus employing multiple inheritance versus adding an object as a member of an object; deciding to make a function a method of an object or creating a new object which performs the function on an input argument of the original object; using inline functions (space/time tradeoffs); and splitting an larger object into subjects. While it is great to have these choices, there can be significant benefit to optimially choosing amongst these possibilities. With C, you simply don't have these constructs to choose amongst. With assembly, you have even less constructs to choose amongst.

Last Edited: Sun. Dec 23, 2007 - 11:32 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have appended a reference implementation that works as intended (tested with cygwin).

Interesting is the (deviously hidden) need for a copy and assignment operator. Though the same kind of compiler support is needed in the C example too.

I have also tested the C++ implementation (without printf, no optimisation) using Code Warrior for a HC908 target. Resulting in:

Summary of section sizes per section type:
READ_ONLY (R):         163 (dec:      355)
READ_WRITE (R/W):       30 (dec:       48)
NO_INIT (N/I):          48 (dec:       72)

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm not quite sure how to plan to use the C++ challenge. But, for C, wouldn't the standard idiom for efficiency is to pass pointers to the objects rather than the objects themselves. Your C++ code does that by passing references (which are pointers to the objects) rather the objects themselves.

Pages