Sunday, June 20, 2010

The Siren Call of "the C++ ABI"

In a recent email thread on the ACCU-general mailing list, Adrian Fagg came out with the immortal statement:

"You might think that calling direct to C++ across those boundaries is a triumph of technology, I think it's a siren luring you onto the rocks."

This is so cool, I'm almost speechless. (Yes, my friends, I could never actually be speechless. Perhaps I should say "This is so cool, I'm experiencing a temporary diminution of my garrullous and overweening eloquence"? Perhaps not.)

Anyhoo, this would have a been a great quote to lead into part 2 of Imperfect C++, which covers a number of issues regarding C++'s non-standard, tricky, and limiting attempts at ABIs.

Friday, June 11, 2010

Imperfect C++ Inventions: dimensionof


dimensionof() is a macro, also known as STLSOFT_NUM_ELEMENTS(), for compile-time array size evaluation.


Its purpose is to calculate, at compile time, the dimension of an array, whilst rejecting, as a compile-error, application of the macro to a pointer or an instance of a user-defined type that has a subscript operator.

int ar[1];
int* pi =  &ar[0];
std::vector vi;

STLSOFT_NUM_ELEMENTS(pi); // compile error
STLSOFT_NUM_ELEMENTS(vi); // compile error


When I started programming C and C++ in the early 1990s, one of the first things I did was create a NUM_ELEMENTS() macro, defined as:

  #define NUM_ELEMENTS(x) (sizeof(x)/sizeof((x)[0]))

Some years later, after reading Peter van der Linden's excellent Deep C Secrets, I realised I could reverse the subscript operator, and instead define it as:

  #define NUM_ELEMENTS(x) (sizeof(x)/sizeof(0[(x)]))

Then, as part of the STLSoft project, I worked out a method of applying function templates taking references to arrays of a deducible dimension, in the form of the macro STLSOFT_NUM_ELEMENTS(). The details of the technique are discussed in chapter 14 of Imperfect C++, and the implementation shown in the online documentation.

In the latest alpha release of STLSoft 1.10, the header file stlsoft/util/dimensionof.h introduces the dimensionof() macro, as a syntactic alias for STLSOFT_NUM_ELEMENTS(). The reason it's in a separate header is because, unlike STLSOFT_NUM_ELEMENTS(), it does not have an unambiguous name.

It has no dependencies.


Throughout the STLSoft libraries, and also used widely in dependent libraries such as b64, FastFormat, Pantheios, recls and VOLE.

Further Reading

  • The most comprehensive explanation is to be found in chapter 14 of Imperfect C++.