With these #define
s without arguments
#define r 31
#define UMASK (0xffffffffUL<<r)
#define LMASK (0xffffffffUL ^ UMASK)
will UMASK
be identical to (0xffffffffUL<<31)
and LMASK
be identical to (0xffffffffUL ^ (0xffffffffUL<<31))
in the actual code? Which is
uint32_t x = (state_array[k] & UMASK) | (state_array[j] & LMASK);
I want the compiler to see it as
uint32_t x = (state_array[k] & 0x80000000UL) | (state_array[j] & 0x7fffffffUL);
I just cannot decode the standard enough to spell it out.
will
UMASK
be identical to(0xffffffffUL<<31)
Yes.
and
LMASK
be identical to(0xffffffffUL ^ (0xffffffffUL<<31))
Yes.
As the macro replacement text for UMASK
is scanned, the token r
will be recognized as a macro and 31
will be copied, so the UMASK
result follows.
As the macro replacement text for LMASK
is scanned, the token UMASK
will be recognized as a macro and expanded as before, so the LMASK
result follows.
The C11 standard §6.10.3 Macro replacement ¶9 specifies the expansion of object-like macros:
A preprocessing directive of the form
# define identifier replacement-list new-line
defines an object-like macro that causes each subsequent instance of the macro name171) to be replaced by the replacement list of preprocessing tokens that constitute the remainder of the directive. The replacement list is then rescanned for more macro names as specified below.
Footnote 171 isn't germane to this discussion.
§6.10.3.4 Rescanning and further replacement details the scanning that occurs while processing the replacement text.
After all parameters in the replacement list have been substituted and
#
and##
processing has taken place, all placemarker preprocessing tokens are removed. The resulting preprocessing token sequence is then rescanned, along with all subsequent preprocessing tokens of the source file, for more macro names to replace.If the name of the macro being replaced is found during this scan of the replacement list (not including the rest of the source file's preprocessing tokens), it is not replaced. Furthermore, if any nested replacements encounter the name of the macro being replaced, it is not replaced. These nonreplaced macro name preprocessing tokens are no longer available for further replacement even if they are later (re)examined in contexts in which that macro name preprocessing token would otherwise have been replaced.
The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one, but all pragma unary operator expressions within it are then processed as specified in 6.10.9 below.