Even after many years of working with C and C++, I continue to make new discoveries! All these years I had returned 0 from the main function on success and a non-zero value (almost always 1) on failure. Somewhere at the back of my head it had always troubled me that there was no standardization on these return values and that I was returning what were essentially magic numbers.

I recently discovered that though the C and C++ languages do not have anything to say about this issue (like they rightly should not), the C and C++ standard libraries do provide EXIT_SUCCESS and EXIT_FAILURE. These can be used to return from the main function. These are defined in the stdlib.h and cstdlib headers for C and C++ respectively.

Curious to see what values they represented, I looked up /usr/include/c++/5/cstdlib and found this:

#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1

Tried with: GCC 5.2.1 and Ubuntu 15.10


C: Ternary Operator with Omitted Operand

The gcc compiler supports an alternate syntax of the ternary operator:

x = a ? : b;

This is called a ternary operator with omitted operand. This is shorthand for:

x = a;
if ( !x )
    x = b;

This is almost like, but is not like:

x = a ? a : b;

The difference is that a might be a function with side effect. This alternate syntax of the ternary operator ensures that a is processed only once (and not twice like in the second version).

This extension does not seem to be supported in the Visual C++ compilers.

C: Initializer List

A common practice in C is to initialize the elements of arrays and structures to zero like this:

int iarr[3]    = { 0 };
struct Foo foo = { 0 };

Experienced C programmers know that this kind of initialization works only for zero, not for any other value! πŸ™‚ For example, this will not initialize the elements of the array or structure to -1:

int iarr[3]    = { -1 };  // Initialized to [-1, 0, 0]
struct Foo foo = { -1 };

The above only initializes the first element of the array or structure to -1. The rest are initialized to 0.

The single initializer shown in examples above is just a special case of an initializer list that does not completely handle all the elements of the array or structure. For such partial initializer lists, C will step in and initialize the rest of the elements to 0. For example:

int iarr[3] = { -1, 99 }; // Initialized to [-1, 99, 0]

Finally, modern compilers like Visual C++ provide an easier alternative to initialize all the elements to zero:

int iarr[3] = {}; // Initialized to [0, 0, 0]

For more on initializer lists, refer to Appendix A.8.7 in The C Programming Language (2nd Edition).