How to get C standards

C standard development follows a process similar to the C++ standard. Working group 14 or WG14 works on C standards and all relevant information can be found at its website.

The drafts closest to the released standards are:

The complete list of drafts can be found here as PDF files named nXXXX.pdf.

Advertisements

Integer division in C

Integer division in modern C always rounds towards zero.
For example:

9/2 = 4
-9/2 = -4 (not -5)

This was was not always so. In early C versions and in the C89 standard, positive integer division rounded to zero, but result of negative integer division was implementation dependent!

From Β§3.3.5 Multiplicative operators of the C89 standard:

   When integers are divided and the division is inexact, if both
operands are positive the result of the / operator is the largest
integer less than the algebraic quotient and the result of the %
operator is positive.  If either operand is negative, whether the
result of the / operator is the largest integer less than the
algebraic quotient or the smallest integer greater than the algebraic
quotient is implementation-defined, as is the sign of the result of
the % operator.  If the quotient a/b is representable, the expression
(a/b)*b + a%b shall equal a .

The same appears in the first edition of The C Programming Language book by Kernighan and Ritchie.

This implementation-defined behavior was fixed by the C99 standard which defined that integer division always rounds towards zero.

From Β§6.5.5 Multiplicative operators of the C99 standard:

When integers are divided, the result of the / operator is the algebraic
quotient with any fractional part discarded.

Thanks to Arch for pointing this out.

EXIT_SUCCESS and EXIT_FAILURE in C and C++

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).