In the C++0x 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++0x 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 L'\x0' - L'\x1' < 0 #error non-C++0x preprocessor arithmetic. #else #error C++0x preprocessor arithmetic! L'\x0' and L'\x1' are widened to\ unsigned long long #endifThe 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++0x preprocessor and the C++0x preprocessor.
#if ~0ull == 0u + ~0u #error C++0x preprocessor arithmetic! 0u has the same representation as 0ull,\ hence ~0ull == 0u + ~0u #else #error non-C++0x preprocessor arithmetic. 0ul does not have the same \ representation as 0ull, hence ~0ull != 0u + ~0u #endifIf this feature is disabled and -qwarn0x is set, the C++0x preprocessor evaluates the controlling expressions in the #if and #elif directives, and compares the evaluation results against that of the non-C++0x preprocessor. If they are different, the compiler warns you that the preprocessor controlling expression evaluates differently between C++0x and non-C++0x language levels.
Mixed string literal concatenation
#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
//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
#line 1000000 //Valid in C++0x, but invalid in C++98 int main() { return 0; }
Diagnostic for object-like macro definitions
//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.
#pragma comment(copyright, "IBM 2010") _Pragma("comment(copyright, \"IBM 2010\")")
_Pragma("comment(copyright, \"IBM 2010\")") int main() { return 0; }
Variadic macros and empty macro arguments
#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));