“Why, yes; and not exactly that either. The fact is, we have all been a good deal puzzled because the affair is so simple, and yet baffles us altogether.”
― Edgar Allan Poe, The Purloined Letter

Below, you find a little C project that doesn’t do what it’s supposed to do, namely print the sum of the first 10 prime numbers. The program builds cleanly with gcc and clang; that is, without any warnings even when using -Wextra -Wall -pedantic -ansi as compiler options. It’s well-formed and doesn’t crash.

What’s the root cause of this bug? What’s the output of the program? Here are the files, you can also find them on GitHub:

Today, I want to share a little C++ container class with you that has proved useful over the years: const_map. I finally got around to turning it into something reusable, or so I hope. Special thanks go to John Hinke, who provided awesome feedback.

In simple words, const_map is an associated array, just like good ol’ std::map: a mapping from keys to values which allows you to lookup values by keys:

1

2

constchar*color_name=color_names[eColorRed];

cout<<"Look, Ma, "<<eColorRed<<" is called "<<color_name<<endl;

Contrary to std::map, however, const_map is a read-only container. To set it up, you provide a key/value mapping table to the constructor:

1

2

3

4

5

6

7

8

9

10

11

enumColor{eColorBlack,eColorRed,eColorGreen,eColorBlue,};

// The mapping table.

const_map<Color,constchar*>::value_type COLOR_NAMES[]={

{eColorRed,"red"},

{eColorGreen,"green"},

{eColorBlue,"blue"},

};

// The const_map.

const_map<Color,constchar*>color_names(COLOR_NAMES);

Once a const_map is instantiated, it’s not possible to add or remove key/value pairs anymore:

1

color_names[eColorBlack]="black";// Error: const_map is read-only!

Just like std::map, const_map’s runtime is O(log(n)). Contrary to std::map, the implementation isn’t based on binary trees but on binary search. Hence, the mapping table must be sorted by key in ascending order.

const_map doesn’t do any heap allocations. All it does is maintain two pointers: one to the beginning and another one to the end of the mapping table. Apart form these two pointers, const_map doesn’t need any other state or housekeeping data. Thus, on a 32-bit platform, const_map instances will cost you eight measly bytes of RAM.

Now, I know there are some embedded cheapskates out there to whom even eight bytes is sometimes too big a sacrifice. If you’re so tight on RAM and are willing to forgo the fancy STL-like interface and rather expend a little bit more typing, you can use the static class member function ‘lookup’ which is completely stateless and doesn’t require an instance:

I’ve mostly used const_map as a replacement for long, unwieldy switch-case abominations. Either to translate values from one data type to another or to determine which action to take based on a given value. In the latter case, my value type was a function pointer or functor.

“Boredom is just the reverse side of fascination: both depend on being outside rather than inside a situation, and one leads to the other.”
— Arthur Schopenhauer

Winter is definitely approaching. The days are getting shorter and temperatures are dropping. Isn’t this a wonderful time for doing code katas? Sitting in your easy chair, in front of a fireplace, serenely coding away in your favorite editor.

Today, we dip once more into the realm of low-level embedded programming. Your primary job is to write code that reverses the bits of an integer. For instance, reversing the 8-bit integer value 139 (10001011) yields a new value of 209 (11010001).

Sounds simple, doesn’t it? But it’s not just about coding a bit-reversing routine, that wouldn’t teach you enough lessons. You’ll also practice unit testing, code tuning and — if you like — assembly language programming, cross-compilation, and remote debugging along the way.

The goal is not to find the best/fastest algorithm possible. Instead, the emphasis is on exercising your programming muscle and learning new things. Don’t rush this kata, rather consider it a mini project. Do the research, be persistent. Try and fail and become better. Take your time, I did it over a period of three weeks. Now, without further ado, let’s get (gently) started.

I certainly learned a lot by doing this kata. Far more, than I can possible tell here without risking to bore you and/or spoil all the fun. Nevertheless, I uploaded my work to GitHub. Have a peek in case you get stuck, need some inspiration or are just curious.

There’s a rather obscure feature in C99 which allows you to put the ‘static’ keyword between the brackets when declaring array-like parameters to functions, as in

1

2

3

voidtransform(uint8_t buffer[static42]){

...

}

What this means, in a nutshell, is that the caller of this function is expected to pass an array of at least 42 uint8_t’s. Calling ‘transform’ like this would be perfectly OK:

1

2

3

4

5

uint8_t buffer1[42];

transform(buffer1);

uint8_t buffer2[100];

transform(buffer2);

whereas this would constitute a breach of contract:

1

2

uint8_t buffer3[10];

transform(buffer3);// Error

Likewise, passing a NULL pointer is not allowed, as it — by definition — doesn’t point to anything, not even a single element:

1

transform(NULL);// Error

THE QUEST FOR MEANING

While the semantics of this feature are pretty clear, the purpose isn’t. The C99 language standard doesn’t give a hint, either.

Even when ‘static’ is used, the called function ‘transform’ doesn’t know the exact size of the array. It only knows that it comprises at least 42 elements, so it can only reliably utilize 42 elements. There’s nothing ‘transform’ can do with any (potential) extra elements, because there might be none. So what’s different to this?

1

2

3

voidtransform(uint8_t buffer[42]){

...

}

This question haunted me for days (if not weeks) and I just couldn’t find a satisfying answer. But let’s put it aside for a moment, as I still have a lot to critisize regarding the technicalities.

THE SYNTAX

First off, why on earth ‘static’? In C, the keyword ‘static’ has already overloaded meanings: a) module scope (an object or function declared ‘static’ is private to a translation unit) and b) lifetime (a static object defined within a function retains its value across invocations). Thanks to C99, ‘static’ now can also mean “at least”. Yuck!

Had I been forced to specify this feature, I would have used the ‘>=’ operator instead of ‘static’:

1

2

3

voidtransform(uint8 buffer[>=42]){

...

}

THE DANGERS

One of the biggest and most infamous blunders in engineering is when you don’t have a single point of truth; that is, the same information is stored in more than one place. Over time, inconsistencies arise in the copies which can lead to all kinds of havoc. All software engineers are reminded again and again to honor the DRY principle.

According to the grammar, ‘static’ can appear in function declarations as well as function definitions. Nobody prevents you from declaring ‘transform’ like this in your header file:

1

voidtransform(uint8_t buffer[static41]);

and like so in a C file:

1

2

3

voidtransform(uint8_t buffer[static42]){

...

}

The C99 standard says nothing about such inconsistencies, whether it constitutes an error, which one takes precedence, whether the compiler has to emit a warning message.

Another problem is that C99 also introduced variable-length arrays (VLAs) and hence an array’s size is not required to be a compile-time constant, like it used to be in C89 and like it still is in C++. Therefore, the C99 grammar blesses such abominations:

1

2

3

4

5

intmy_global=42;

voidtransform(uint8_t buffer[staticmy_global]){

...

}

What’s the contract now? At least 42 elements (the value of ‘my_global’ at program start-up) or the value of ‘my_global’ when ‘transform’ is actually called:

1

2

3

4

5

intmy_global=42;

...

my_global=100;

uint8_t buffer4[42]

transform(buffer4);// OK?

Again, if you’d forced me to specify this feature, I’d required the size specifier to be a compile-time constant:

1

2

voidtransform(uint8 buffer[>=my_global]);// Error

voidtransform(uint8 buffer[>=42]);// OK

AN EPIPHANY

While ranting about this feature, I suddenly had an epiphany. Let’s revisit the question I asked above: What’s really the difference between

1

2

3

voidtransform(uint8_t buffer[42]){

...

}

and

1

2

3

voidtransform(uint8_t buffer[static42]){

...

}

since my doubts regarding the usefulness of this feature are 100% founded in this question. Previously, I believed that in the second case, there are at least 42 elements, while in the first case there are exactly 42 elements. Not a big difference, because what benefit would a compiler be able to derive from this subtle difference?

But I obviously fell into a trap that I warned my readers a long time ago: believing that array parameters are really arrays, which is mistaken, of course, because arrays cannot be passed directly to functions. From the C language’s point of view, the former interface of ‘transform’ is equivalent to

1

2

3

voidtransform(uint8_t*constbuffer){

...

}

which means that ‘buffer’ is a pointer to a single ‘uint8_t’, nothing more, nothing less. The compiler can’t make any assumptions beyond that, it’s obliged to ignore the fact that you indicated that there are 42 elements. Specifically, all these declarations are equivalent and effectively declare a function taking a pointer to a ‘uint8_t’:

1

2

3

4

voidtransform(uint8_t buffer[1]);

voidtransform(uint8_t buffer[42]);

voidtransform(uint8_t buffer[1000]);

voidtransform(uint8_t buffer[]);

By contrast, the version of ‘transform’ that uses ‘static’ tells the compiler that a pointer to the first of at least 42 elements is passed. Armed with this knowledge, the compiler can now perform certain optimizations, the most likely one being accessing memory in units much larger than a ‘uint8_t’, to save memory access times. Ah!

ADVICE

Even though we now understand the motivation behind this feature, I still wouldn’t recommend using it. Just like it’s the case with many other so-called “optimization” features (e. g. ‘inline‘ and ‘restrict‘) you, as a developer, have to keep a promise but get nothing dependable back from the compiler. As usual, my advice is this: if you think something needs to be optimized, prove it first; if evidence shows that optimization is necessary, optimize in a dependable way — don’t rely on something that might change from one compiler version to another, especially if it comes with an hideous interface that invites inconsistencies.

ONE MORE THING

Thinking about this odd feature once again, what it all boils down to is that ‘static’ with function parameters actually tries to deliver what regular array-like parameters can’t, namely inform the compiler that the pointer that is passed is really an array, not just a pointer to a single element. But there’s already a feature in the C language (available since C89) that achieves that, namely pointers to arrays:

1

2

3

4

5

6

7

8

9

10

11

12

typedefuint8_t BUFFER42[42];

voidtransform(BUFFER42*buffer){

...

}

BUFFER42 buffer42;

transform(&buffer42);

typedefuint8_t BUFFER10[10];

BUFFER10 buffer10;

transform(&buffer10);// Compile-time error

Contrary to ‘static’ with array parameters, pointers to arrays is a clean, proven, and type-safe concept. Since the compiler knows how many elements the array comprises, it can apply the same optimizations that the ‘static’ with array parameters feature promises, that is, accessing multiple elements at once when traversing the array. There’s really no reason to put ‘static’ between your array brackets, trust me.

When you go back to C/C++ after a week of coding in Python, funny things can happen. I already described such a case in this post.

Recently, I had another surprising incident. I was scanning my code changes in order to find a bug that had pestered me for quite a while. I rubbed my eyes in disbelief when I came across this ‘if’ statement:

1

2

3

if((sensorIndex>=MAX_SENSORS)and(repeat==REPEAT_CYCLIC)){

...

}

How could this even compile? Instead of ‘&&’ I inadvertently typed ‘and’, the Python logical ‘and’ operator. At first, I thought that this must either be a g++ extension or some clever guy* had defined

1

#define and &&

somewhere in a header file that I pulled. Being biased towards the second theory, I did an experiment and undefined ‘and’ just before my ‘if’ statement:

1

#undef and

but it didn’t compile. Luckily, the compiler message that I got from g++ unraveled the mystery:

1

error: "and" cannot be used as a macro name as it is an operator in C++

Whoa! ‘and’ is an operator (a token) in C++ that hitherto I’d never heard of. In fact, there’s a whole bunch of what the C++ standard calles “alternative tokens” (or sometimes “alternative representations”):

Alternative Token

Equivalent To

and

&&

and_eq

&=

bitand

&

bitor

|

compl

~

not

!

not_eq

!=

or

||

or_eq

|=

xor

^

xor_eq

^=

It didn’t take long and the feeling of surprise was replaced with a feeling of disappointment. Some of the bit-wise operators have a ‘bit’ prefix while others don’t. ‘and’ and ‘bitand’, for instance, but ‘and_eq’ should actually be ‘bitand_eq’, because ‘&=’ is a bitwise operator — sigh! The same goes for ‘or’, ‘bitor’ and ‘or_eq’. By the same token (pun intended!), ‘xor’ and ‘xor_eq’ should really be ‘bitxor’ and ‘bitxor_eq’, if you’d ask me.

Not so confusing, actually quite beneficial, are the operators ‘and’, ‘or’, and ‘not’ by themselves. Consider:

1

2

3

4

5

6

7

8

9

10

11

if((i>0)and(k>0)){

...

}

if((x==0)or(y==0)){

...

}

if(notvalid){

...

}

While using these newly discovered keywords is certainly not a huge thing, I do believe that alternative operators are more readable than their cryptic, traditional counterparts. Habitually used, they even avoid classic blunders like forgetting to put a second ‘&’ or ‘|’ in logic expressions. I think I’ll give them a try — but this time as a deliberate act, instead of a Freudian slip like last time.

Note, however, that in C, these alternative representations don’t exist as keywords. Instead, they are defined in iso646.h as macros — just like the “clever guy” would have done it :-)

________________________________

*) Once, such a “clever guy” made fun of our team’s coding standard by defining this macro (the letter O) in a global header file:
#define O (1 – 1)
and using ‘O’ in his code whenever he needed a literal ‘0’ (zero):
for (int i = O; i < max; ++i) {
…
}
When I asked him why on earth he did such an insane thing, he replied, “Well, our coding standard says that we MUST not use octal literals, but 0 is an octal literal since it starts with a ‘0’. Smartass! ↩

Considering all the C++ job offers that I’ve received over the last couple of months, it looks like modern C++ (any C++ release beyond C++03) is picking up momentum, especially in embedded systems. Why embedded systems? I think it’s because C++ has always put a lot of emphasis on efficiency and thus the features offered by C++11 and C++14 not only simplify a programmer’s life but also stand a good chance of yielding more performant code. Now that C++11 and C++14 are supported by almost all contemporary compilers, there’s no reason to hold back anymore.

Alas, reading standard documents or even books on the subject is no fun. While the idea behind new features is usually easy to grasp, there are often intricacies that dim a feature’s shine. Clearly, studying books and learning about subtleties is necessary at some point, but isn’t there an accelerated way to get started (or motivated)?

Now there is, at least that’s my goal with this new project that I’ve created: The Happy Path to Modern C++. The idea is to tackle modern C++ by example not by text; that is, by code snippets that demonstrate the beauty of language features, not their nitty-gritty details.

Every code snippet can be compiled and run in a debugger to explore its behavior. Thus familiarizing (and experimenting) with modern C++ language features should be painless (maybe even fun?).

Let me show you what I mean. The following snippet (which is part of cpp11/01_core_features/core_features.cpp) introduces range-based for-loops:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

//////////////////////////////////////////////////

// Range-based for-loops simplify iteration over

// sequences.

voidtest_range_based_for_loops(){

vector<int>values{23,42,19};

for(autov:values){// 'v' is a local copy of item.

cout<<v<<endl;

v+=1;// Value change is lost.

}

for(auto&v:values){// 'v' is a reference to an item.

cout<<v<<endl;

v+=1;// Item value updated in vector.

}

for(constauto&v:values){// 'v' is a const reference to an item.

cout<<v<<endl;

// v += 1; // Error: 'v' is read-only.

}

}

Just go to cpp11/01_core_features and execute

1

make

to compile the code and

1

make test

to run it.

With this set-up, it’s easy to toy around: just uncomment the line in ‘test_range_based_for_loops’ that constitutes a syntax error (the line that attempts to modify the read-only variable), rerun make and see what happens. Contrast this hands-on approach with the (fine) documentation on cppreference.com, which is exact and comprehensive (and ten times more readable than the official language standardese), but nevertheless intimidating for beginners.

Be aware that you are looking at work in progress. My aim of this first release was to cover most of C++11 and C++14 core language features as well features pertaining to classes. Obviously, a lot is still missing, like

Contributions to this project are more than welcome, just send me your pull requests. Please keep in mind that the overall goal is to have crisp code examples that capture the essence of features, not the ugly corner cases. When in doubt, leave it out, keep it simple, keep it beautiful.