5.14.1.1 Preprocessor Arithmetic
Preprocessor macro replacement expressions are textual and do not utilize types. Unless they are part of the controlling expression to the inclusion directives (discussed below), macros are not evaluated by the preprocessor. Once macros have been textually expanded and preprocessing is complete, the expansion forms a C expression which is evaluated by the code generator along with other C code. Tokens within the expanded C expression inherit a type, with values then subject to integral promotion and type conversion in the usual way.
If a macro is part of the controlling expression to a conditional
inclusion directive (#if
or #elif
), the macro must be
evaluated by the preprocessor. The result of this evaluation is sometimes different from
the C-domain result for the same sequence. The preprocessor processes unsigned and signed
literal integer values in the controlling expression as if they had the respective type
uintmax_t
or intmax_t
, defined in
<stdint.h>
. For the MPLAB XC8 C Compiler, the size of these types is 64 bits.
MAX
to be the
result of a 64-bit multiplication, 0xF4240. However, the definition of the long
int
variable, max
, will be assigned the value 0x4240 (since
the constant 1000 has a signed int
type, and therefore the C-domain
multiplication will also be performed using a 16-bit signed int
type).#define MAX 1000*1000
...
#if MAX > INT16_MAX // evaluation of MAX by preprocessor
long int max = MAX; // evaluation of MAX by code generator
#else
int max = MAX; // evaluation of MAX by code generator
#endif
Overflow in the C
domain can be avoided by using a constant suffix in the macro. For example, an
L
after a number in a macro expansion indicates it should be
interpreted by the C compiler as a long
, but this suffix does not affect
how the preprocessor interprets the value, if it needs to evaluate it.
#define MAX 1000*1000L