Readable function pointers

Consider the following declaration

char*(*(*foo)(int(*)(char*,char*)))[]

It’s artificial (generated with the ever-helpful geordi bot), although I’m sure that if you looked hard enough, a similar one would appear somewhere in the wild. In the above case, foo is a pointer to function taking pointer to function taking char* and char* and returning int returning pointer to array of char*. I think that even seasoned C and C++ programmers will agree that this is quite confusing at first glance. Or second. And third. Especially for people less versed in “C gibberish”, as cdecl.org aptly calls it.

Right angle brackets and backwards compatibility

Ever since introduction of C++03 the standard committee set out to fix many minor annoyances in the language (auto, ranged for and initializer lists to name a few). Most of those are new things that cannot change the behaviour of existing code, but there are, of course, exceptions. In C++03 the first line of the following code was ill-formed, because >> was parsed as operator>>.

std::vector<std::vector<int>>  X; // ill-formed
std::vector<std::vector<int> > Y; // ok

Parentheses that change everything

It is well known — and intuitively understood by most — that adding a set of parentheses usually doesn’t change anything; for example, int answer = 42; is equal to int answer = (42); or int answer = ((42));. There are some important exceptions to that rule, however, and I’ll talk about these in this post.

Macros

Although macros are rarely used in good C++ code, it is important to be able to understand what’s happening and why. Using a popular example of MIN macro, the naïve implementation would look like this:

#define MIN(x,y) x < y ? x : y

To a beginner, this would look like a correct implementation, and indeed, it would work in some cases; for example, answer below would indeed be equal to 42:

int answer = MIN(42,50);

Unfortunately, macros are expanded as text, and in the following example, possibly surprisingly, answer would hold the value of 41 instead:

int answer = 2 + MIN(40,41);

C’s secret operator: goes to

Consider the following code:

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
 
using namespace std;
 
int main()
{
	int n = 10;
 
	while(n --> 0)
		cout << "n: " << n << endl;
}

Should it compile? If your answer is yes, what should be its output?