The 2011 revision of the ISO standard for C (dubbed "C11") provides several ease-of-use features, most of which are compatible with C++11. In order to use the normal-looking names I'll show here, you need to include these headers: <stddef.h>, <stdlib.h>, <assert.h>, <complex.h>, <stdnoreturn.h>, <uchar.h>, <stdatomic.h>, and <stdalign.h>.

Alignment

C11 and C++11 both provide new syntax for specifying alignment. The expression alignof(type-name) designates the alignment of type-name; it is a constant expression, as is the familiar sizeof(type-name) . (There's one exception in C: Applying sizeof to a variable length array, or VLA, produces a non-constant expression.) The expression alignof(char) is, of course, always 1.

There is a similar syntax for declarations:

int alignas(double) b;

specifies that b is an int , but is aligned suitably for a double . Or for a more realistic example,

alignas(double) unsigned char buf[sizeof(double)];

specifies that buf is an array of unsigned char , whose size and alignment would be suitable to hold a double .

Alignment can be specified as an integer: alignas(constant-expression) specifies the constant-expression as an alignment. Thus, alignas(type-name) means the same thing as alignas(alignof(type-name)) .

For each target platform, there is some type that has the largest alignment requirement; that type can be named by the typedef max_align_t , so a declaration that specifies alignas(max_align_t) requests an alignment that will be suitable for any type on that platform. If a program requests an alignment that is greater than alignof(max_align_t) , the program is not portable because support for an over-aligned type is optional.

The C11 library provides aligned_alloc(size_t bound, size_t nbytes) , which allocates nbytes of storage aligned on a bound boundary. The most common use case heard by the committee was to request a buffer aligned on a cache boundary (typically 32k or 64k); however, you have to check your own compiler's manual because the implementation gets to determine the valid alignments.

Unicode Strings and Constants

The new u8 prefix for strings creates a string (an array of char ) that is encoded using the UTF-8 encoding. If your text editor and your compiler are using the ASCII representation (most are), then the string u8"John Doe" will contain the same characters as the ordinary string "John Doe" . The crucial difference comes when your program needs to represent international characters beyond the basic 7-bit ASCII (English) characters. If your text editor and compiler can handle the characters, then your program could contain a string like u8"α Ä Ǽ Ω" and pass that string to the various C library functions that handle ordinary strings (arrays of char ).

The UTF-8 encoding is increasingly popular; for example, it is the default encoding for XML. To the extent that you have a choice about character representations, it appears to me with the benefit of decades of hindsight, that UTF-8, using the u8 strings, is the simplest and best choice.

However, you may not have this simple choice, so C11 (and C++11) also provide several other Unicode representations. A string like u"αΩ" creates an array of char16_t values (encoded in UTF-16); similarly, a string like U"αΩ" creates an array of char32_t values (encoded in UTF-32). Also, there are character constants for char16_t and char32_t values, written as u'α' and U'α' . Unfortunately, if you need to use these more complex features, you may need to know about endian-ness, surrogate characters, differences between Windows and UNIX/Linux representations, and this overview article cannot provide enough details to address all those issues.

Type-Generic Macros

The C99 standard introduced type-generic macros into the standardized library. For example, you could invoke fabs(x) , where x is either float , double , or long double . What happened auto-magically was that invocation of the type-generic macro abs would cause invocation of one of three separate library functions fabsf(float) , fabs(double) , or fabsl(long double). However, in C99, you had no opportunity to use the same magic for your own purposes. Now, in C11, you can create a fabs(x) that will be portable to any other C11 compiler:

#define fabs(X) _Generic( (X), \ long double: fabsl, \ default: fabs, \ float: fabsf \ ) (X)

This method defines a macro named fabs , which will cause the invocation of several different library functions, using the new C11 syntax for the _Generic keyword. That fabs macro is an ordinary macro defined in the preprocessor. For example, fabs could be undefined (using #undef ). As you see, type-generic macros provide only a tiny portion of the full-blown overloading that is available in C++, but it's enough for purposes such as the type-generic math library.

Miscellaneous Ease-of-Use Features

It is now possible, in C11 and C++11, to inform the compiler that a function will not return. For example, exit is a function that does not return, so it can be declared like this:

noreturn void exit(int status);

Using noreturn in this way can assist the compiler's optimizer, possibly eliminating unnecessary warnings.

C11 and C++11also provide static_assert(constant-expr, string-literal) ; if the constant-expr is zero, then a diagnostic message containing the text of the string-literal will be printed. As the name implies, the static_assert is evaluated at compile time, so it can prevent compilation with incompatible options; for example

static_assert(sizeof(void*) == 4, "64-bit code generation not supported");

One common use of static_assert is to verify that resource configuration is adequate:

static_assert(NUMBER_OF_BUCKETS >= 16, "NUMBER_OF_BUCKETS must be at least 16");

The message produced by static_assert will contain, ind addition to the string-literal argument, the file name, line number, and function name (if any).

The C11 standard provides three macros that are helpful for C/C++ compatibility for programs that use complex floating-point values:

double complex CMPLX(double x, double y); float complex CMPLXF(float x, float y); long double complex CMPLXL(long double x, long double y);

Your C++ version of the program could create corresponding macro definitions (but the C++11 standard does not provide these):

#define CMPLX(x, y) std::complex>double<((double)x, (double)y) #define CMPLXF(x, y) std::complex>float<((float)x, (float)y) #define CMPLXL(x, y) std::complex>long double<((long double)x, (long double)y)

Finally, there's a committee decision that was inadvertently left out of the published standard: The pre-defined macros _ _STDC_VERSION_ _ and _ _STDC_LIB_EXT1_ _ are defined to be 201112L .

Several other corrections and improvements were made, which won't be itemized here.