C99 preprocessor features adopted in C++11 (C++11)

Note: IBM supports selected features of C++11, known as C++0x before its ratification. IBM will continue to develop and implement the features of this standard. The implementation of the language level is based on IBM's interpretation of the standard. Until IBM's implementation of all the C++11 features is complete, including the support of a new C++11 standard library, the implementation may change from release to release. IBM makes no attempt to maintain compatibility, in source, binary, or listings and other compiler interfaces, with earlier releases of IBM's implementation of the new C++11 features.

In the C++11 standard, several C99 preprocessor features are adopted to provide a common preprocessor interface for C and C++ compilers. This eases porting C source files to the C++ compiler and eliminates some subtle semantic differences that exist between the old C and C++ preprocessors, thus avoiding preprocessor compatibility issues or diverging preprocessor behaviors.

Preprocessor arithmetic with extended integer types

In the C89, C++98, and C++03 preprocessors, integer literals that have int or unsigned int type are widened to long or unsigned long. However, in the C99 and C++11 preprocessors, all signed and unsigned integer types (character types included) are widened to long long or unsigned long long under normal circumstances in XL C/C++.

If this feature is enabled, and both -qnolonglong and -qlanglvl=noc99longlong are set in either -q32 or -q64 modes, the preprocessor still uses long long or unsigned long long representations for all integral and character literals in preprocessor controlling expressions.

The following example is valid on the AIX® platform in -q32 mode where the underlying type of wchar_t is unsigned short.
#if L'\x0' - L'\x1' < 0 
#error non-C++11 preprocessor arithmetic. 
#else
#error C++11 preprocessor arithmetic! L'\x0' and L'\x1' are widened to\
       unsigned long long 
#endif 
The following example shows a case where the long long support is enabled in -q32 mode, this feature causes different inclusion branches to be chosen between the non-C++11 preprocessor and the C++11 preprocessor.
#if ~0ull == 0u + ~0u 
#error C++11 preprocessor arithmetic! 0u has the same representation as 0ull,\
       hence ~0ull == 0u + ~0u 
#else 
#error non-C++11 preprocessor arithmetic. 0ul does not have the same \
       representation as 0ull, hence ~0ull != 0u + ~0u 
#endif

If this feature is disabled and -qwarn0x is set, the C++11 preprocessor evaluates the controlling expressions in the #if and #elif directives, and compares the evaluation results against that of the non-C++11 preprocessor. If they are different, the compiler warns you that the preprocessor controlling expression evaluates differently between C++11 and non-C++11 language levels.

Mixed string literal concatenation

Regular strings can be concatenated with wide-string literals, for example:
#include <wchar.h>
#include <stdio.h>

int main()
{
wprintf(L"Guess what? %ls\n", "I can now concate" L"nate regular strings\
        and wide strings!");
printf("Guess what? %ls\n", L"I can now concate" "nate strings\
        this way too!");
}
This example prints the following output when it is executed:
Guess what? I can now concatenate regular strings and wide strings!
Guess what? I can now concatenate strings this way too!

Diagnostic for header files and include names

When this feature is enabled, if the first character of a header file name in an #include directive is a digit, the compiler issues a warning message. Consider the following example:
//inc.C

#include "0x/mylib.h"

int main()
{
return 0;
}
When compiling or preprocessing this example with this feature enabled, the compiler issues the following warning message:
"inc.C", line 1.10: 1540-0893 (W) The header file name "0x/mylib.h" 
in #include directive shall not start with a digit.

Increased limit for #line directives

The upper limit of the #line <integer> preprocessor directives has been increased from 32,767 to 2,147,483,647 for the C++11 preprocessor in conformance with the C99 preprocessor.
#line 1000000   //Valid in C++11, but invalid in C++98
int main() 
{
    return 0;
} 

Diagnostic for object-like macro definitions

If there is no white space between object-like macro name and its replacement list in a macro definition, the C++11 compiler issues a warning message. Consider the following example:
//w.C

//With -qnodollar, '$' is not part of the macro name,
//thus it begins the replacement list
#define A$B c 
#define STR2( x ) # x 
#define STR( x ) STR2( x )  
char x[] = STR( A$B ); 
When compiling or preprocessing this example with this feature enabled and -qnodollar is specified, the compiler issues the following warning message:
"w.C", line 1.10: 1540-0891 (W) Missing white space between 
the identifier "A" and the replacement list.

The _Pragma operator

The _Pragma operator is an alternative method of specifying #pragma directives. For example, the following two statements are equivalent:
#pragma comment(copyright, "IBM 2010")
_Pragma("comment(copyright, \"IBM 2010\")")
The string IBM 2010 is inserted into the C++ object file when the following code is compiled:
_Pragma("comment(copyright, \"IBM 2010\")")
int main() 
{
   return 0;
}

Variadic macros and empty macro arguments

Variadic macros and empty macro arguments are supported in C99 and C++11. This feature enables a mechanism that renames the variable argument identifier from __VA_ARGS__ to a user-defined identifier. Consider the following example:
#define debug(...) fprintf(stderr, __VA_ARGS__) 
#define showlist(...) puts(#__VA_ARGS__)
#define report(test, ...) ((test)?puts(#test): printf(__VA_ARGS__))
debug("Flag"); 
debug("X = %d\n", x);
showlist(The first, second, and third items.);
report(x>y, "x is %d but y is %d", x, y); 
This example is expanded to the following code after preprocessing:
fprintf(stderr, "Flag");
fprintf(stderr, "X = %d\n", x);
puts("The first, second, and third items.");
((x>y)?puts("x>y"): printf("x is %d but y is %d", x, y));

Predefined macros

The __STDC_HOSTED__ macro is predefined to 1, regardless of whether the following macros are defined or not:
  • __STDC__
  • __STDC_VERSION__
  • __STDC_ISO_10646_