#define
directive lets you define preprocessor-time constants and macros.
Syntax:
#define id [token-string]
or
#define id([id, [id, […]]) [token-string]
A macro declaration must end on the same line. If you need to continue on the next line, finish a line with a backslash character:
#define MY_STRING "This is a start of the long " \
"long long " \
"string" // the end of macro declaration
In its first form, #define creates a preprocessor-time constants. For example:
#define MAX_LENGTH 5
This declaration will instruct the preprocessor to scan the source file and replace all occurrences of MAX_LENGTH
with 5
. The preprocessor is smart enough to only perform a replace when MAX_LENGTH
is used as an identifier, that is, it will transform the following code fragment:
// This example uses MAX_LENGTH:
struct A
{
int array[MAX_LENGTH];
const int MaxLength = MAX_LENGTH;
$assert(MaxLength == MAX_LENGTH, "Error with MAX_LENGTH");
};
into the following:
// This example uses MAX_LENGTH:
struct A
{
int array[5];
const int MaxLength = 5;
$assert(MaxLength == 5, "Error with MAX_LENGTH");
};
As you see, substitution had not occurred in comment and in string. All other occurrences have been replaced.
A constant may be more complex, for example:
#define MAX_LENGTH (2 + 5)
Note the use of parenthesis in order to prevent operator precedence errors.
Defined constants may refer to constants defined before:
#define SECOND 10000000
#define MINUTE (60 * SECOND)
The following form:
#define SOME
will only define a constant, without assigning it a particular value. If occurred in a text, it gets removed from it. However, you may successfully test such constant within the #ifdef
directive or using a defined()
operator:
#define INCLUDE_STRUCT_A
// …
#ifdef INCLUDE_STRUCT_A
struct A
{
// …
};
#endif
By convention, macros and preprocessor constants are named with uppercase letters.
The second form of the directive is used to define macros:
#define ADD(x,y) ((x) + (y))
The preprocessor will not only perform a replace, but also will perform a parameter substitution:
ADD(7,8) // will be replaced with ((7) + (8))
ADD(n,-1) // will be replaced with ((n) + (-1))
Macros may contain any number of parameters:
#define MAX(a,b) ((a) > (b) ? (a) : (b))
Device Monitoring Studio supports variadic macros. To use variadic macros, the ellipsis may be specified as the final formal argument in a macro definition, and the replacement identifier __VA_ARGS__
may be used in the definition to insert the extra arguments. __VA_ARGS__
is replaced by all of the arguments that match the ellipsis, including commas between them.
An #undef
directive is used to remove the macro definition.
Syntax:
#undef id
Example:
#define MAX_LENGTH 5
struct A
{
int array[MAX_LENGTH];
};
#undef MAX_LENGTH
struct B
{
// compile-time error, "MAX_LENGTH" identifier not found
// (preprocessor did not replace it with "5")
int array[MAX_LENGTH];
};