#define directive (macro)

Preprocessor directive that creates a function-like macro.

#define identifier( argument0, ... , argumentN-1 ) token-string


Item Description
Identifier of the macro.
A second #define for a macro with an identifier that already exists in the current context generates an error unless the second token sequence is identical to the first.
( argument0, ... , argumentN-1 )
List of arguments to the macro. The argument list is comma-delimited, can be of any length, and must be enclosed in parentheses. Each argument name in the list must be unique. No white space can separate the identifier parameter and the opening parenthesis.
Use line concatenation place a backslash (\) immediately before the newline character to split long directives onto multiple source lines.
token-string [optional]
Value of the macro. This parameter consists of a series of tokens, such as keywords, constants, or complete statements. One or more white-space characters must separate this parameter from the identifier parameter; this white space is not considered part of the substituted text, nor is any white space following the last token of the text. Make liberal use of parentheses to ensure that complicated arguments are interpreted correctly.
If the value of the identifier parameter occurs within the token-string parameter (even as a result of another macro expansion), it is not expanded.
If you exclude this parameter, all instances of the identifier parameter are removed from the source file. The identifier remains defined, and can be tested using the #if defined, #ifdef, and #ifndef directives.


All instances of the identifier parameter that occur after the #define directive in the source file constitute a macro call, and the identifier will be replaced by a version of the token-string parameter that has actual arguments substituted for formal parameters. The number of parameters in the call must match the number of parameters in the macro definition. The identifier is replaced only when it forms a token; for example, the identifier is not replaced if it appears in a comment, within a string, or as part of a longer identifier.

The #undef directive instructs the preprocessor to forget the definition of an identifier; for more information, see #undef Directive (DirectX HLSL).

Defining constants with the /D compiler option has the same effect as using the #define directive at the beginning of your file. Up to 30 macros can be defined with the /D option.

The actual arguments in the macro call are matched to the corresponding formal arguments in the macro definition. Each formal argument in the token string is replaced by the corresponding actual argument, unless the argument is preceded by a stringizing (#), charizing (#@), or token-pasting (##) operator, or is followed by a ## operator. Any macros in the actual argument are expanded before the directive replaces the formal parameter.

Token pasting in the HLSL compiler is slightly different from token pasting in the C compiler, in that the pasted tokens must be valid tokens on their own. For example, consider the following macro definition:

#define MERGE(a, b) a##b
MERGE(float, 4x4) test;

In the C compiler, this results in the following:

float4x4 test

In the HLSL compiler however, this results in the following:

float4 x4 test

You can work around this behavior by using the following macro definition instead.

MERGE(MERGE(float, 4), x4) test;


The following example uses a macro to define cursor lines.

#define CURSOR(top, bottom) (((top) << 8) | (bottom))

The following example defines a macro that retrieves a pseudorandom integer in the specified range.

#define getrandom(min, max) \
((rand()%(int)(((max) + 1)-(min)))+ (min))

Preprocessor Directives (DirectX HLSL)

#define Overloads

#undef Directive (DirectX HLSL)