Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
ChaunceyGardiner
PostPosted: Apr 21, 2012 - 11:21 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

stevech wrote:
ChaunceyGardiner wrote:
There are plenty of advantages besides "dots in the function name".
In the context of embedded processor code that is easily maintained by other than the author, what are the C++ advantages? I've spent a lot of time learning C++ (coming from decades of C), and haven't yet found what's better than good modularized C with lots of typedefs and structs (for embedded).


Function overloading, template functions, loop variables, reference variables and type safety for starters. Those are just off the top of my head, the list is much longer.

For the skilled C++ developer - classes, class templates, inheritance, improved resource handling, easier creation and use of reusable code, less duplication of code and so on.
 
 View user's profile Send private message  
Reply with quote Back to top
westfw
PostPosted: Apr 22, 2012 - 01:19 AM
Posting Freak


Joined: Jun 19, 2002
Posts: 1331
Location: SF Bay area

Quote:
template functions

I've seen Arduino folk use "template functions" to good effect, but they're not something I've come across in my reading of "introductory C++", so I've always assumed that they were one of those tools used by "advanced" tools writers, sort-of like stringification and catenation in multi-line macros would be in C.

But now you have it in the "immediately useful" category, while other concepts that the introductory texts are big on (classes, inheritance), you have in the "skilled" category.

Tell me more (point me to) more about templates and when they are appropriate/etc...

(This does point out one of the big problems with C++ in the embedded space. The usual TEACHING of C++ is done in ways that tend to be incompatible with deeply embedded systems. "we can make a class purpleWindow that inherits most of its behavior from the normal XYZGrpahicsWindow class, and use "new" to put them all over our display.")
 
 View user's profile Send private message  
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 22, 2012 - 01:39 AM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

westfw,

Template functions aren't that hard to understand. For instance, consider this:
Code:
template<class T>
inline T min(T a, T b)
{
    return a < b ? a : b;
}

int i = min(1, 2);
This, as opposed to a macro, adds type safety, lacks side effects and will give you a more or less sensible error message if you try to compare apples to oranges and assign the result to a peach.

Also note that C code compiled as C++ will have to conform to a stricter standard, which allows you to avoid some of the common pitfalls of C. C is way too lenient.

The reason I put classes and inheritance in the "skilled C++ developer" list is that you need some knowledge about the code generated in different cases before you can put this to good use in a context with limited resources.

The same goes for using new – it should be avoided when not necessary, and you need skills to know when it's necessary. The skilled C++ developer will avoid this on any platform, but the consequences of lacking this knowledge are bigger on embedded systems because of the limited resources.
 
 View user's profile Send private message  
Reply with quote Back to top
smileymicros
PostPosted: Apr 22, 2012 - 02:23 AM
Raving lunatic


Joined: Nov 17, 2004
Posts: 6479
Location: Great Smokey Mountains.

<sarc>
Oh yes that is so much easier and clearer than:
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
</sarc>

_________________
FREE TUTORIAL: 'Quick Start Guide for Using the WinAVR C Compiler with ATMEL's AVR Butterfly' AVAILABLE AT: http://www.smileymicros.com
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 22, 2012 - 02:30 AM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

smileymicros wrote:
<sarc>
Oh yes that is so much easier and clearer than:
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
</sarc>

Yes, it is. There is no telling what X and Y might be.

The parenthesis doesn't help readability, either.

The main point of using the template version, though, is that your user source code looks the same while there are less ways to fudge things up.
 
 View user's profile Send private message  
Reply with quote Back to top
stevech
PostPosted: Apr 22, 2012 - 07:21 AM
Raving lunatic


Joined: Dec 18, 2001
Posts: 5219


Opinion: Chauncey's remarks above about the merits of C++, function overloading (for me, it makes for confusion during debugging); Inheritance - if it's all compile-time, since in my embedded work there's not enough RAM to fool with new/Malloc; Better resource management: If one doesn't (cannot) do object creation/deletion in a small RAM micro, is this applicable? ; Templates - yes, these are better than Macros, but the learning curve on Templates is daunting, and I worry that it would be too obtuse to understand a year later.

In my C++ studies, I figured out how (couldn't find in texts) for an ISR to have shared variables with a static instance of a class' variables. Never have figured out how to "friend" those to protect from access by other than the class functions and the ISR. Nor have I figured out (other than an ugly way) for a class instance at run time (new) to collaborate with an ISR, on a CPU without memory management like our little 8 bitters.

I welcome the rebuttal!

I have written a couple of AVR-targeted thousand-line C++ programs which include ISRs (in C, not C++), and have mastered the basics of C++ with static instances of classes (no malloc). That's good enough, I suppose, for micros with just a few KB of RAM. A garbage collector for RAM (free()) in some instances can cause unpredictable timing for an embedded micro. And worse, iterating to try to conjoin free'd RAM blocks. Not gonna work in 4KB RAM devices without multi-tasking.

Good discussion.
 
 View user's profile Send private message  
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 22, 2012 - 02:34 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

stevech,
Using classes doesn't mean you have to use new, just like using C structs doesn't mean you have to use malloc. Think of classes as C structs, where you can take advantage of additional features if you want to.

You worry about unrestricted access to your class members. While that is good thinking if it leads you to a good solution, it doesn't make much sense worrying about this when the "solution" is to go back to C and allow everything access to everything.

The ISR use of an object boils down to this : are you able to access a C struct from your ISR ? If so, what stops you from accessing an object the same way ? C++ classes are C structs. It's just that you're allowed to do more with them.

Most of the things you have given up on finding out are things you could have asked about in a suitable forum. That applies to function templates too - if you find them hard to learn, post a macro you want to convert to a template and ask how to do it. The fact that you can create complicated templates doesn't mean that you have to make them complicated. And complicated macros are worse anyway.
 
 View user's profile Send private message  
Reply with quote Back to top
stevech
PostPosted: Apr 22, 2012 - 06:26 PM
Raving lunatic


Joined: Dec 18, 2001
Posts: 5219


Chauncey... Of course, classes can be static. And I assert, they must be in a small RAM micro, especially when deterministic timing is necessary as is often the case in small micro embedded.

I did start a dialog here on how to properly access variables in a C++ class from an ISR, or vice-versa. I didn't get a usable answer, and the 'net and texts didn't tell me, so I resorted to trial and error. Probably still don't have it right. It's because of the name-mangling C++ does and the C based ISR doesn't.

I'll be the first to day that despite a lot of time on C++ and ISRs and so on, I still don't know what I don't know. Wish there were a proper and in depth tutorial on this, in the context of 8 bit micros with small RAM and bare metal (no OS).
 
 View user's profile Send private message  
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 22, 2012 - 06:54 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

stevech,

It's not clear to me what you mean when you use the word "static" like you do.

The lack of learning material for efficient use of C++ on embedded systems is one of the reasons I separated "advanced" stuff from easy stuff. You can use the easy stuff without years of experience.

Name-mangling can be turned off by using extern "C".

You will need a reference to your object to use inside the ISR, just as you would need a reference to your struct if you did it in C.
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Apr 22, 2012 - 07:58 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 21397
Location: Lund, Sweden

Quote:

Chauncey... Of course, classes can be static.

Or automatic.

I assume here that we are talking about the allocation of them, i.e. "static, automatic or dynamic" as those terms are used in C. They can be used the same in a C++ context.

The confusion arises because the language keyword 'static' exists in C++, and while there are philosophical similarities this is a different "mechanism".

When using "static" in a C++ context, make sure it is clear from the context if the allocation scheme (i.e. static-automatic-dynamic allocation of objects) or the keyword (e.g. as in "a static member") is intended.

Quote:

And I assert, they must be in a small RAM micro

So must a C struct. No difference.

Here is the gist of it:

- If you in C need to handle only one istance of a data structure then you set up that data structure as one or several global and let a set of C functions operate on them. You will not have control of that other functions meddle with the data structures. In C++ you package the data and the functions in a class, making all members static, and use the access restrictions of classes (public, protected, private) to shield your data structure form "external meddling". No extra cost involve as compared to C.

- If you need to handle several instances of the data in C, then your functions will have to take (a pointer to) the data structure as a parameter. Again your data structure will be available for "meddling". And you will have to pass the data explicitly to all your functions. In C++ you protect your data as above, the difference being that now data and functions are not declared static. C++ will implicitly pass a pointer to the instance data, the 'this' pointer. There will be no extra cost involved as compared to C.

- If you don't want/need inheritance then there will be no extra cost involved not using it in C++. If you do want/need inheritance then...

- if it is non-polymorphic inheritance then C++ will help you with that. You might pull this off with C, but you as a programmer would be the one responsible for calling the correct version of a function. In C++ the compiler will do that for you. Just as for the case above with no inheritance there will be no extra cost as compared to C.

- if it is polymorphic inheritance (or if you wilsh "using virtual member functions in C++") then you can get away with this in C also, but again there will be no help from the compiler. Your C source code will be full of convoluted function calls and handling of tables of virtual function pointers. Again, the C++ compiler will be helping you here at no extra cost as compared with the C implementation.

And again, if you opt not to use a C++ feature, there will be no cost for it.

For the discussion on ISRs, the most straight-forward solution seems to be to implement the ISR as a C function, and if performance so demands make it a friend of the class for which it needs to manipulate data. If the performance demands aren't high, then you could let it call a member function of the class (and pay the usual penalty for calling a function from an ISR).

Or you could let the ISR follow the idiom of setting a global flag and perhaps a variable, let the main loop inspect the flag and manipulate the object. This is a compromise, but I'm not religious about C++ so if that works in a specific situation that might be fine for me.

None of the statements on performance above is a statement on any specific compiler, and a badly written C++ compiler could well be very inefficient. There is nothing inherent in C++ that makes it inefficient for the above cases, though. A badly written compiler is a badly written compiler and could/should be criticized regardless of what language it compiles.

Finally: If you take the stance that you dislike or am reluctant towards <any thing> then you will have a hard time learning it. If you are reasonably skeptic but curious in a positive way, you will have an easier time. If <any thing> is actually C++ and you are reluctant or disliking it, then you will be better off not going for it. There is room for both C and C++ - use what makes you happy, not what makes you sad.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 22, 2012 - 08:12 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

I agree with everything Johan just wrote. However, it is important - especially in the context of small embedded systems - to be aware of what code is actually generated by some C++ features (typically related to classes). It is possible for the programmer to affect this, but it takes experience to know what to do and what not to do.

_________________
Sid

Life... is a state of mind
 
 View user's profile Send private message  
Reply with quote Back to top
coverclock
PostPosted: Apr 23, 2012 - 04:04 PM
Newbie


Joined: Mar 08, 2012
Posts: 13
Location: Denver Colorado USA

It's easy to get into a C versus C++ argument because both parties are right.

I'm old enough (almost a brain in a jar connected to wires and tubes) that I remember the assembler versus C arguments when I was writing real-time stuff for PDP-11s in assembler. And the assembler folks are right too. In the 1990s even as I was writing in C++ for one chip on a board I was also writing code in assembler on DSPs on the same board. Just depends on the circumstances.

But part of my goal in this project was to figure out if the C++ techniques I'd been using since 1996 on PowerPC and ARM processors could be carried over to eight-bit microcontrollers. The answer, for me, was "yes". Not that it doesn't take discipline and care. You can write inefficient, hard to maintain, buggy code in C++, just as you can in C, and for that matter in assembler.

C++'s greatest strength is also it's greatest weakness: it allows you to climb higher on the abstraction ladder. This can reduce your development costs, both short term and long term, and can also reduce your project to a smoking heap of crap. Climbing higher on the abstraction ladder does not free you from having to know what's going on under the hood.

This is really always true, but is especially always true in highly resource constrained environments. ("Especially always" meaning elsewhen you can get away with being ignorant without being bitten right away... unfortunately.)

I don't believe C++ is a good language for students just starting out to learn programming. It's just too darn complicated. I like Java, or script-like languages like Python (which I've never used, but colleagues whose opinions I trust recommend it).

But for more experienced students who are beginners at embedded, I think C++ is a win. And for very experienced embedded developers who are looking for more capability from their language, it is a big win.

I like OO design. My first experience at OO design was working with the OS/360 I/O Subsystem written circa 1969, although I first started poking at it in 1976. No, I'm not kidding. Almost all the mechanisms that C++ uses under the hood I first saw in IOS.

Algorithms have two big picture components: action, and state. The question "which is more important, action or state?" is meaningless, it's like asking "which is more important to life, blood or oxygen?"

OO languages are a way of combining action and state into a single lexical component, with some rules to prevent developers from inadvertently dealing with one but not the other. Back when I was using C for pretty much all development, i found myself writing in a style that combined action and state (structures and functions). C++ gave me the means to combine the two in a way that the language supported what I wanted to do automatically.

Thank you, thank you, I'll be here all week. Don't forget to tip the bartender!
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
smileymicros
PostPosted: Apr 23, 2012 - 05:15 PM
Raving lunatic


Joined: Nov 17, 2004
Posts: 6479
Location: Great Smokey Mountains.

coverclock wrote:
Algorithms have two big picture components: action, and state. The question "which is more important, action or state?" is meaningless, it's like asking "which is more important to life, blood or oxygen?"

OO languages are a way of combining action and state into a single lexical component, with some rules to prevent developers from inadvertently dealing with one but not the other. Back when I was using C for pretty much all development, i found myself writing in a style that combined action and state (structures and functions). C++ gave me the means to combine the two in a way that the language supported what I wanted to do automatically.
This is an excellent statement - thank you!

I've often said that anyone who does enough assembly programming will eventually invent C-like methods for organizing his code. I'm guessing the same applies for C, anyone who does enough of it (especially in teams) will likely develop methods that are C++-like.

There is a lot of gray in the area for folks starting out on microcontrollers. I'm coming to take to Johan's idea that lots of folks will be coming from higher level programming and therefore will already be OOP oriented so they could start out with C++. Unfortunately from my perspective, I don't honestly think I have the experience to lead that charge, so I'll stick with the never-ever programmed folks and continue to promote C. I'll just be fairer when I hear the novice C or C++ argument.

Smiley

_________________
FREE TUTORIAL: 'Quick Start Guide for Using the WinAVR C Compiler with ATMEL's AVR Butterfly' AVAILABLE AT: http://www.smileymicros.com
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
coverclock
PostPosted: Apr 23, 2012 - 06:06 PM
Newbie


Joined: Mar 08, 2012
Posts: 13
Location: Denver Colorado USA

Quote:

I've often said that anyone who does enough assembly programming will eventually invent C-like methods for organizing his code. I'm guessing the same applies for C, anyone who does enough of it (especially in teams) will likely develop methods that are C++-like.


Well said. That has been my experience exactly. Before I ever heard the term "structured programming" back in the 1970s I found myself writing structured programming constructs in assembler just because it was the only way I'd found to write reliable, debuggable, understandable code.

BTW, different sub-thread, I have written some on using C++ templates in embedded projects. As usual, the higher level the language, the more tools it gives you to shoot yourself in the foot, so approach with caution.

http://coverclock.blogspot.com/2007/01/ ... using.html

I would NOT recommend trying to use the C++ STL on an eight-bit microcontroller (the underlying library won't have the STL stuff anyway, so non-issue). But careful use on less constrained PowerPC and ARM platforms has been a win in my experience, and use of your own templates even on AVRs etc. can be a win if done very carefully. Templates used correctly also fall into the category of "automating what you were doing by hand anyway" and depending on the application may have zero additional overhead. Templates are a form of code generation, just like the C preprocessor, and like the CPP, can be great or terrible.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 23, 2012 - 06:23 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

smileymicros wrote:
I'll stick with the never-ever programmed folks and continue to promote C.

Nothing wrong with that, but why dismiss the approach I suggested ? No matter how far you go, you will benefit.

For instance, if you just compile your C code as C++, the compiler will enforce some very good programming habits.

From there, you may be tempted to take advantage of several easy to understand C++ improvements, while your source code still looks pretty much like C.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Apr 23, 2012 - 07:00 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 69423
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

From there, you may be tempted to take advantage of several easy to understand C++ improvements, while your source code still looks pretty much like C.

I'd agree this is the best approach. Start with C in .cpp files but then maybe start to dabble in namespaces or classes with member functions (the infamous class.function() syntax), then use things like function over-loading.

A bit like when you make the transition to C99 you just start to use the new bits then wonder how you ever lived without them.

I'd be interested to hear from the C++ experts here what is the best 10 features to dabble in first(*). A bit like when the MCU programmer starts and does:

1) light LED
2) blink LED with delay loops
3) blink LED with timer
4) PWM LED to fade up/down
5) read pot using ADC and use to vary blink/fade/etc.
6) and so on...

(*) with emphasis on MCU usage!

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
smileymicros
PostPosted: Apr 23, 2012 - 08:42 PM
Raving lunatic


Joined: Nov 17, 2004
Posts: 6479
Location: Great Smokey Mountains.

coverclock wrote:
As usual, the higher level the language, the more tools it gives you to shoot yourself in the foot, so approach with caution.


Quote:
"C makes it easy to shoot yourself in the foot. C++ makes it harder, but when you do you blow your whole leg off." - Bjarne Stroustrop


I'll probably wait a few more years and then start working on teaching materials for embedded Linux on an ARM using C++. It seems to me we really are in a transition point where transistors are becoming so cheap that adequate systems will be available for a few dollars. Really the only thing in the way in the moment are well documented free and easy tools like WinAVR. I assume in the next few years these tools and documents will become available.

Smiley

_________________
FREE TUTORIAL: 'Quick Start Guide for Using the WinAVR C Compiler with ATMEL's AVR Butterfly' AVAILABLE AT: http://www.smileymicros.com
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 23, 2012 - 09:02 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

clawson wrote:
I'd be interested to hear from the C++ experts here what is the best 10 features to dabble in first(*).

(*) with emphasis on MCU usage!
My first attempt at such a list :
    1) declare variables at first use
    2) loop variables
    3) bool data type
    4) function overloading
    5) default parameters
    6) new[] and delete[]
    7) template functions
    8) simple classes, i.e. C-style structs with the addition of non-virtual member functions
    9) simple class inheritance
    10) exception handling (if the overhead is acceptable)
Some of those may be included in C99 ? I ditched C for C++ more than 20 years ago, so I don't stay fully updated on C.
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Apr 23, 2012 - 09:44 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 21397
Location: Lund, Sweden

Quote:
8 ) simple classes, i.e. C-style structs with the addition of non-virtual member functions

I'd probably have that as #1 . Apart from the "addition of member functions" you also have to deal with access specificers (public-protected-private), constructors and destructors. And then you have the concept of aggregation (ie objects within objects) and then you will have to return to talking about constructors and destructors and the order in which they are executed. And I'm probably missing a lot of things. There is enough here for items #1 to #5 on the list...

Quote:
7) template functions

No opinion on that ordering, but I'd say that template classes should be on the list and are more important than template functions. I've taught C++ many times (a three day introductory course), and while we always introduced templating with template functions I am actually wondering if that is the wise way. Don't get me wrong - both are usable, but while template functions are convenient template classes are about something much bigger. Think "Abstract Data Types" if that term is familiar.

Quote:
3) bool data type

I could deem this a detail, if it wasn't for another big difference between C and C++: While C has the type concept, there is very little inherent type safety. C++ is a lot stronger here. And the notion of "a real boolean type" is an indicator of that C++ was designed with types as a central concept.

Quote:
9) simple class inheritance

I'd have this fairly early on the list, definitively before any templating.

Quote:
6) new[] and delete[]

Where did new and delete disappear? Quatum leap to dynamic allocation of arrays of objects - oh my! Wink
Quote:

1) declare variables at first use
2) loop variables
4) function overloading
5) default parameters

All details in the big picture. Not simply syntactic sugar perhaps, but not central to "thinking in C++".

Quote:
10) exception handling (if the overhead is acceptable)

I'll have to think about this..

-----

I have a few "mental mantras" about OO:

Mantra 1: Encapsulation, Inheritance, Polymorphism

Mantra 2: Favour aggregation instead of inheritance.

Mantra 3: Program against an interface.

Mantra 4: Initialize in the constructor, tear down in the destructor (a.k.a RAII).

Those would control and influence the items, and the order of them, on my C++ list.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 23, 2012 - 10:36 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

Johan,

My list is ordered more or less according to ease of use for the experienced C developer.

What I wrote about “simple” classes is aimed at this audience. They would be better served by starting with C structs, only adding non-virtual member functions, as this adds no implicit overhead. Throw in constructors, destructors and aggregation and you increase the demands on the developer’s knowledge considerably – especially in the context of embedded systems. Also, starting with a C struct means that you don’t have to deal with access specifiers. Keep it simple, once people master the basics they may (or may not) decide to learn more.

Simple function templates are useful and easy to understand. Big gain, small cost.

new and delete should be avoided whenever they are not needed, for the skilled C developer it’s best to avoid them completely unless he is mallocing structs in his C code.

new[] and delete[] on the other hand is a type-safe alternative to malloc()/calloc() (to create C arrays), and easy to understand for the skilled C developer.

Template classes are best avoided until you are fully competent on classes.

What you refer to as “details in the big picture” are simple little things that improves your source code, and they most likely appeal to the skilled C developer that can immediately use them. They are small details to you and me, but good points for convincing others that there may be something to this other language even without years of study.

I don't disagree with you about C++ but you have the wrong focus for this audience.
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits