Names can be defined and undefined for use in pre-processing. A #define
defines an identifier. A #undef
"undefines" an identifier – if the identifier was defined earlier then it becomes undefined. If an identifier is defined then it is semantically equivalent to true
; if an identifier is undefined then it is semantically equivalent to false
.
The example:
#define A #undef B class C { #if A void F() {} #else void G() {} #endif #if B void H() {} #else void I() {} #endif }
becomes:
class C { void F() {} void I() {} }
Within a pp-unit, declarations must precede pp-token elements. In other words, #define
and #undef
must precede any "real code" in the file, or a compile-time error occurs. Thus, it is possible to intersperse #if
and #define
as in the example below:
#define A #if A #define B #endif namespace N { #if B class Class1 {} #endif }
The following example is illegal because a #define
follows real code:
#define A namespace N { #define B #if B class Class1 {} #endif }
A #undef
may "undefine" a name that is not defined. The example below defines a name and then undefines it twice; the second #undef
has no effect but is still legal.
#define A #undef A #undef A