C++ Programming

Overview

This page covers C++ programming and it’s use in embedded programming.

DID YOU KNOW? – C++ started out as a preprocessor for C, before later developing into it’s own language.

One of my favourite quotes:

C makes it easy to shoot yourself in the foot…C++ makes it harder, but when you do, it blows your whole leg off. – Bjame Stroustrup

Child Pages

Boost Libraries
Information of various boost libraries such as shared_ptr, and common error messages while using boost libraries.
C++ On Embedded Systems
Tip and tricks when using C++ on an embedded system.
C++ Timing
How to use timers, delays and timing-related features in the C++ programming language.
Callbacks
How to deal with the important but-ever-so-difficult issue of callbacks in the C++ programming language.
Classes
Classes are what makes C++ an object orientated language.
Code Checkers
A review on C++ code checkers.
Const Correctness
Making sense of the const keyword when used (potentially multiple times) in a line of C++ code.
Containers
C++ provides a large number of different data storage methods (called containers) in it's standard library. Learn about vector, deque and more!
Dealing With Strings
Dealing with strings (sequences of multiple characters) in C++, especially in an embedded context.
Exceptions
How to use exceptions in the C++ programming language.
Inheritance
This page deals with an important object-orientated construct, inheritance.
Input And Output
Dealing with input and output (IO, this includes streams) in C++.
Linux Bash Commands For C++
Bash commands for compiling and working with the C++ language in Linux.
Operator Overloading
What is operator overloading, and how to use it.
References
Info and examples on C++ references (the & operator), and how they differ from C-style pointers.
Smart Pointers
How to make your C++ experience better by using the concept of smart pointers.
Special Casts
C++ gives you a few special cast functions.
Type Conversion
Type conversion, casting and ambiguity.
Virtual Methods
Virtual methods allow methods of inherited classes to be overridden and pointers to work correctly.
Warning And Error Message Help
Common warning and error messages you will come across when programming in C++.

Benefits Over C

  • Namespaces
  • Classes (which are just fancy and more powerful structs!)
  • Function overloading (differing number of input variables for the same function name)
  • Operator overloading (e.g. a + sign could do whatever you want it to do, not necessarily add. Good for making things like imaginary number and fixed-point arithmetic intuitive).
  • Stricter variable type conversions, resulting in less type related errors (with more cast keywords such as static_cast<>() , dynamic_cast<>() e.t.c)
  • High-level programming (this can also be a disadvantage, due to loss in transparency)
  • Enumeration constants can have the same name (as long as they are in different namespaces/classes).
  • More system libraries. C++ has all of the standard C libraries plus an extended set of useful libraries.
  • No implicit conversion between void*  and char* , this has to be explicitly defined
  • You get a constructor which is called when an object is created. In many cases this can replace remembering to call the traditional Init() function.
  • The ability to quickly change a variable/function from private to public (useful for debugging/testing).
  • A full explanation of the source code from just looking at the header file (the class definition includes private objects as well as public).
  • Parameters lists for creating constructors

Disadvantages Over C

  • Not as much support for embedded systems. Any self-respecting embedded system has a compiler for C. However, C++ compilers are less common. Saying that, many of the most popular microcontrollers such as the ATmega, 8-bit Arduino’s (which uses an ATmega anyway) support C++. And some of those that don’t can be hacked to compile C++ (e.g. PSoC 5).
  • Less transparent, loss of exact control over what the compiler generates
  • More memory issues, greater code footprint (potentially)
  • Function pointers no longer work the same way when they point to a function in a class (aka point to a member function)
  • Non-static class variables can’t be initialised at the same time as the declaration (they have to be initialised either in the constructor or a purpose made Init()  function.
  • It’s more complicated! Every heard of a protected abstract virtual base pure virtual private destructor? Well, in C++, they do exist!

To read more about the differences, see this wonderful article, C++ tutorial for C users.

Mixing C With C++

C code can be mixed (aka compiled) with/alongside C++ code. One important thing to note that C can be compiled from inside C++ code, but C++ code cannot be compiled from C code. This means that the file that includes main()  must be compiled with C++, but main can call external C functions.

Name Mangling

Name mangling is a technique used by C++ compilers to distinguish overloaded functions of the same name. The compiler adds some seemingly unintelligable characters to the end of overloaded functions (these characters are related to the input variables). C compilers do not do this as the C standard does not support overloaded functions (even though it looks like it, printf(string, variable1, variable2, …) is not overloaded!). When cross-compiling, this has to be taken into consideration.

Compilers

Most embedded C++ compilers use GCC. The main competitor to the GCC compiler is Clang, however it is not as common in embedded environments (I have never personally used Clang to compile for an embedded application).

See the Linux Bash Commands For C++ page for a quickstart C++ guide for Linux.

Constructors

There is a syntax ambiguity in C++ which normally appears when you are trying to create an object of a particular type, and using the default constructor. It is called the “Most Vexing Parse“.

Constructors cannot be declared static, as it makes sense that they only belong to an object of that class type. If you want to initialise static member variables, you do this in the normal C way, outside of the class definition.

Constructors can take parameter lists, which along with constructors, is a new concept that is not present in C.

Namespaces

Namespaces give you the ability to wrap functions and variables into groups. Calling functions or accessing variables within a namespace requires you to use the :: syntax, or by using the using namespace blah  syntax (see the code examples below).

This removes the need for the common C convention of prefixing all functions with the name of the file they are in (for example, files in Uart.c would be called things like Uart_PutString() and Uart_GetChar().

Strutures

Structures cannot be initialised with the following convention as commonly used in C. Instead, you have to initialise them at run time.

Before creating a structure think, could this be better as a class? After all, classes are structures on steriods, giving you much more functionality.

Qualifiers

static

Inside a class: When static  is used inside a class, it means that a new version of the function/variable will not be created for each instance of the class. All static objects are shared with all instances of the class, and static variables exist from start-up. For this reason, there is no this  object available for any static class function, and so it can’t access the classes non-static members (if you think about this, it makes sense). It also means that creating multiple objects of a class with static members has interesting effects, and you have to consider corruption and thread safety when doing so.

You can’t declare a whole class as static, as you can in C#. All that a static class in C# does if force you to make all of it’s members static also, which you can do anyway in C++.

Static can be a good way to get around the annoying “pointer to non-static member function” error you get when mixing C++ with C (especially in embedded situations). This is because you CAN take a pointer to a static member function. Just remember about the other implications it has!

Forward Declarations

Forward declarations can be used to resolve circular dependencies of pointers to classes (but only pointers, and not circular dependencies of objects, these are illegal).

Note that you cannot write a forward declaration for a class in a different namespace using the <namespace name>::<class name>  syntax, you have to fully “open” the namespace using the namespace <namespace name> { class <class name>; }  syntax, as shown below.

External Resources

My favourite C++ resource is C++ Tutorial For C Users. This is probably because when learning C++ I came from a C background, but even if I ignore that fact I still think this tutorial is layed out nicely. It consists of a single page with numbered headings, and progressively teaches you C++ and the differences with C.

The C++ FAQ is a good site that explains C++ in depth. Nicely organised into hyperlinked sections.

C And C++ In 5 Days is a good PDF which provides help for both C and C++.

If you want to read up on why C++ is what it is, and the thoughts/idea behind one it’s principle designers, read A History Of C++: 1979-1991 by Bjarne Stroustrup