The Point of noreturn
Certain functions can exhibit some unusual behavior. For instance, functions that never return to their caller are rather common in applications that use signals and exceptions. Additionally, some odd beasts such as the POSIX fork()function have the unusual property of returning not once per invocation but twice: once in the parent and once in the child.
Programmers need to be alerted of such unusual behavior when they encounter these functions. Furthermore, compilers often issue a warning when they detect a function call that never returns. Once again, C++09 attributes come to rescue, making your code easier to understand and more secure.
To designate a function that never returns, use the attribute-token noreturn and make sure the first declaration of the function specifies the noreturn attribute. If you declare a function with the noreturn attribute in one translation unit and then declare it without the noreturnattribute in another translation unit, your program will be ill formed.
Here's an example of a noreturnfunction:
void f [[ noreturn ]] ()
throw "failed"; // OK
GCC users may recognize the [[noreturn]] attribute as the equivalent of __noreturn__:
void die(int, void *) __attribute__((__noreturn__)); //GCC
In C++09, you would declare the same function like this:
void die [[ noreturn ]] (int, void *); //C++09
In a previous 10-Minute Solution, I showed how to probe and override the alignment of types and objects. Newsflash: The latest C++09 standard got rid of the alignas keyword (but the alignofoperator remains in the standard).
If you want to override the default alignment of a type or an object, or you want to ensure that the same alignment is used in every environment, use the [[align]] attribute. The align token takes a type or an assignment expression as its argument. (Certain attributes can have an argument clause enclosed in parentheses.) For example, here's how you declare a char array that is suitably aligned for double:
//byte array suitably aligned for double
unsigned char c [[align(double)]] [sizeof(double)];
When multiple alignment attributes are specified for an object, the alignment requirement is set to the strictest (highest) specified attribute. Here is how you would declare a buffer with an alignment requirement of A, holding N elements of type T:
//choose the strictest alignment of the two
T buffer [[align(T),align(A)]] [N];
Tribute to Attributes
Presently, C++09 defines four attribute tokens. Although I don't discuss the details in this article, the fourth token, carries_dependency, specifies dependency propagation into and out of functions. The standard allows implementations to extend the token system by defining compiler-specific attribute tokens. Thus, a hypothetical POSIX compiler may define an attribute token [[returns_twice]], which appertains to the fork()function as follows:
pid_t fork [[returns_twice]] (void);
Look for a deeper examination of the carries_dependencytoken in an upcoming 10-Minute Solution. In the meantime, use attributes to alert the compiler and your fellow programmers to the unusual behavior of some of your programming constructs.