C vs C++ with uControllers

foTONICS

Sep 30, 2011
332
Joined
Sep 30, 2011
Messages
332
Hey all,

I love programming uControllers and for the most part I use C. The other day while chatting with a friend he asked me if I program in C or C++. Now I have to admit I didn't know the difference between the two. I did some research and from what I found C in a top-down approach and is function driven while C++ is object driven.

I will only be using C to program uControllers, that's it. Which is the better option for me, should I teach myself C++?
 

KrisBlueNZ

Sadly passed away in 2015
Nov 28, 2011
8,393
Joined
Nov 28, 2011
Messages
8,393
It depends on the microcontrollers you use.

If you use AVRs or PICs, then C++ is not really appropriate, IMO. If you want to use an object oriented language on a small device, Java might be a better option, using exterrnal storage such as serial Flash. Assuming you don't have the need for speed.

If you're using a device like an ARM or a Freescale beast that isn't so resource-constrained, and you want to make it run like it IS resource-constrained, then C++ could be the answer.

Ostensibly, the benefits of C++ and other object oriented languages are that they make code clear and easier to understand, easier to refactor and modify, and easier to share between multiple developers working on the same project.

I made a few other posts on this subject:
https://www.electronicspoint.com/th...able-integrated-circuits.261975/#post-1562782
https://www.electronicspoint.com/th...oubts-in-embedded-system.263475/#post-1572540
https://www.electronicspoint.com/threads/programming-languages.268188/#post-1605583
 

(*steve*)

¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
Jan 21, 2010
25,510
Joined
Jan 21, 2010
Messages
25,510
If you use AVRs or PICs, then C++ is not really appropriate, IMO

If you're using the Arduino development environment than you're using C++.

That doesn't mean you have to use all the object bells and whistles, but you can if you want to. Most of the arduino libraries (that I've taken the time to view the source code of) are written to use objects.

There's no particular reason why C++ needs to be any more resource hungry than plain vanilla C. Having said that, it's a lot easier to write code that consumes memory at points that you wouldn't expect it to in C++ than in C.

If you're writing in C you're using what was described to me (in about 1982) as using "smart assembler". Many of the constructs translate very easily into assembly language (as they were intended to) even on processors that don't have the auto increment/decrement addressing modes of the PDP-11.

Once you start using objects you tend to start using a lot more memory management as they can be dynamically created and destroyed. This is a major consideration for "small" hardware devices that don't have lots in the way of stacks and memory managers. At this point, apparently simple looking statements can turn into larger and more complex beasts that consume memory and require large numbers of cycles and instructions.

Microcontrollers are not a good place to practice dynamic memory allocation...

But having said that, there is no reason not to use objects to provide interfaces to data in a way that manages the access to it. This is especially true for libraries.
 

KrisBlueNZ

Sadly passed away in 2015
Nov 28, 2011
8,393
Joined
Nov 28, 2011
Messages
8,393
There's no particular reason why C++ needs to be any more resource hungry than plain vanilla C.
Well, an object-oriented approach affects how information is mapped to storage. Heavy reliance on indirect access is not efficient unless you have several pointer registers that can directly address reasonable areas of memory.

For boolean data, forcing all of each object's attributes into a single memory block wastes space and code compared to using a bitstring for each attribute, indexed by object number, which AFAIK you can't do in C++. Unless you want to violate the object oriented principles.
If you're writing in C you're using what was described to me (in about 1982) as using "smart assembler".
"C is combines the elegance and power of assembly language with the readability and maintainability of... assembly language".

Back in 1982 that was probably true, but modern compilers and architectures (NOT small MCUs!) can be extremely efficient; often better than run-of-the-mill-quality assembly language.
But having said that, there is no reason not to use objects to provide interfaces to data in a way that manages the access to it. This is especially true for libraries.
Objects are passed by reference. Whether the reference is (internally) a pointer or not, eventually, objects have to be accessed through pointers. The AVR, and especially the smaller PICs, are horribly inefficient at pointer indirection.

The baseline and mid-range devices (excluding the "enhanced" mid-range devices) have only one static pointer register, and messiness quickly multiplies if you want to use it in an interrupt handler. IMO, these small devices aren't even C-friendly; to C++, they're positively hostile! Larger devices are a different story though.

Many library calls are inefficient for small MCUs too, in any language, because many of them have to use pointers to remain generic.
 

(*steve*)

¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
Jan 21, 2010
25,510
Joined
Jan 21, 2010
Messages
25,510
Well, an object-oriented approach affects how information is mapped to storage. Heavy reliance on indirect access is not efficient unless you have several pointer registers that can directly address reasonable areas of memory.

My actual point (not well stated I agree) is that you can write C in C++. You don't have to use the bells and whistles.

For boolean data, forcing all of each object's attributes into a single memory block wastes space and code compared to using a bitstring for each attribute, indexed by object number, which AFAIK you can't do in C++. Unless you want to violate the object oriented principles.

If you can do it in C you can do it in C++. If you're arguing that C++ doesn't implement objects in the best way possible, I'm not going to argue with you. C++ has lots of evidence of being bolted on to C (which is because this is exactly what happened).

"C is combines the elegance and power of assembly language with the readability and maintainability of... assembly language".

Back in 1982 that was probably true, but modern compilers and architectures (NOT small MCUs!) can be extremely efficient; often better than run-of-the-mill-quality assembly language.

This tends to be an argument for C over assembly language, and, if anything, makes the use of C++ features less of an issue (indeed it makes them possible). Unfortunately it has done nothing for the readability of C/C++.

Objects are passed by reference. Whether the reference is (internally) a pointer or not, eventually, objects have to be accessed through pointers. The AVR, and especially the smaller PICs, are horribly inefficient at pointer indirection.

And so you write code in a way that doesn't require pointer usage as far as possible. Globally (or at least statically) defined variables (of whatever type) that are accessed directly rather than via a pointer passed as a parameter will overcome most of that overhead.

The baseline and mid-range devices (excluding the "enhanced" mid-range devices) have only one static pointer register, and messiness quickly multiplies if you want to use it in an interrupt handler. IMO, these small devices aren't even C-friendly; to C++, they're positively hostile! Larger devices are a different story though.

I wouldn't argue against that much either. Even though most modern optimizing compilers can write generally better assembler than a normal person, they cant always do that, nor can they beat all humans. In a small device, the task is likely to be similarly small, and the optimizer will have less opportunity and the human probably more. The point, however, is C vs C++.

Many library calls are inefficient for small MCUs too, in any language, because many of them have to use pointers to remain generic.

A lot depends on the compiler. If the function is a method of a statically declared object, the compiler *may* be able to inline the call completely and not require any pointers at all (and the same may be true of other non-object function calls). Of course, unless you look you'll never know.

In general, if the code does all of the following:
  • works
  • Is fast enough
  • fits
Then your job is done. Personally, I would prefer to make it work better, run faster, and fit in a smaller memory footprint. Unless there are economic imperatives, that may not happen. It's even less likely to happen if (any of the following):
  • you're a beginner
  • bigger/faster device is cheaper
  • the quantity is small.
When we get a question like:

I love programming uControllers and for the most part I use C. The other day while chatting with a friend he asked me if I program in C or C++. Now I have to admit I didn't know the difference between the two. I did some research and from what I found C in a top-down approach and is function driven while C++ is object driven.

...it demonstrated a fundamental misunderstanding about programming and/or about the differences between C and C++.

The difference between C and C++ is that C++ has a few more bells and whistles that makes certain programming paradigms easier than they would be in C.

"Top down approaches" vs "object driven" are design methodologies more than anything else.

As a general rule, top down and bottom up are both employed. The control and big picture stuff are generally top-down. Interfaces are generally bottom up. Data falls between the two. The language doesn't (or shouldn't) change that.

I will only be using C to program uControllers, that's it. Which is the better option for me, should I teach myself C++?

You should at least be familiar with C++ because you may need to understand code written in C++. An example you google may not be in plain C.
 

KrisBlueNZ

Sadly passed away in 2015
Nov 28, 2011
8,393
Joined
Nov 28, 2011
Messages
8,393
My actual point (not well stated I agree) is that you can write C in C++. You don't have to use the bells and whistles.
You can compile C code with a C++ compiler. But the code is still C code. Likewise, you can also compile assembly language with a C compiler - most of them have some kind of inline assembler capability. But that doesn't make it C code!
The difference between C and C++ is that C++ has a few more bells and whistles that makes certain programming paradigms easier than they would be in C.
Object oriented programming forces the programmer to really think about the best way to define objects at various levels, rather than just writing code and declaring variables as he goes. It forces the programmer to be more disciplined, and this has benefits for maintainability, etc. But if you use those features, you pay a price in efficiency. On a 4 GHz Pentium with 8 GB of RAM, no problem. On a 16 MHz PIC with 2k of RAM, BIG problem!
You should at least be familiar with C++ because you may need to understand code written in C++. An example you google may not be in plain C.
Sure.
 

CDRIVE

Hauling 10' pipe on a Trek Shift3
May 8, 2012
4,960
Joined
May 8, 2012
Messages
4,960
I think I love this discussion. It's more like cerebral combat though. Since I've not advanced passed the level of Basic languages I have only comprehended the information commensurate with a Chimpanzee! :confused:

Kris, congratulations on your elevation to Moderator. I'm surprised that the membership doesn't receive an automated notification.

Chris
 

KrisBlueNZ

Sadly passed away in 2015
Nov 28, 2011
8,393
Joined
Nov 28, 2011
Messages
8,393
LOL Chris :)

BTW I was promoted to moderator in November.

I guess my main argument against using the object-oriented features of C++ on small micros is the memory usage, and the inefficiency of accessing data objects by reference or pointer. If you want to write a compact program using static directly addressed variables and compile it with a C++ compiler, then that's fine, but if it will compile with a C compiler as well, it's not really C++!
 

CDRIVE

Hauling 10' pipe on a Trek Shift3
May 8, 2012
4,960
Joined
May 8, 2012
Messages
4,960
LOL Chris :)

BTW I was promoted to moderator in November.

November!! Actually that's not surprising for me. My wife says I don't notice a damn thing unless it pisses me off. :D

That aside I'm enjoying the discussion. ;)

Chris
 

foTONICS

Sep 30, 2011
332
Joined
Sep 30, 2011
Messages
332
First of all I feel I should let everyone know that this is directly related to the thread where I talk about using a PIC to interface an NRF24L01, here is the link: https://www.electronicspoint.com/th...r-leds-and-buzzers.262731/page-5#post-1608543

It depends on the microcontrollers you use.
I'm using a PIC16F627A. I know that I could make my life a lot easier by using a PIC with built in SPI but I have lots of these PICs around, I'm relatively familiar with them, and I feel that I can learn a lot by actually coding the SPI myself (ignorance aside).

Personally, I would prefer to make it work better, run faster, and fit in a smaller memory footprint
that's typically how I like to work on things, get a basic idea working, then keep tweaking it so it's smaller and more efficient, maybe that's why I like assembly language
 

KrisBlueNZ

Sadly passed away in 2015
Nov 28, 2011
8,393
Joined
Nov 28, 2011
Messages
8,393
I'm using a PIC16F627A. I know that I could make my life a lot easier by using a PIC with built in SPI ...
Whether SPI is done with a peripheral or by bit-banging doesn't make much difference in this context. The main factors that affect an architecture's usability with higher-level, more abstrated languages are the amount of RAM and ROM, the speed, and the number of registers (especially pointer registers) and how efficiently they can be used.

So a baseline or mid-range PIC is, IMO, inappropriate for use with C++'s object-oriented features (they aren't even very suitable for plain old C, IMO), a high-end PIC is much better in this respect.
 

Similar threads

Top