I would be surprised if any compilers break if we use ## and #.
However, using TOSTR or # directly is supposed to mean different
things, and most often you want to use TOSTR.
Here is a simple demonstration program:
#include <stdio.h>
#define MY_FAVORITE_COLOR black
#define TOSTR(x) # x
#define GREETING_1(COLOR) "Hello, lover of " # COLOR
#define GREETING_2(COLOR) "Hello, lover of " TOSTR(COLOR)
int main()
{
puts(GREETING_1(MY_FAVORITE_COLOR));
puts(GREETING_2(MY_FAVORITE_COLOR));
}
Leaving aside the question of whether black is a color or not, this
will print:
Hello, lover of MY_FAVORITE_COLOR
Hello, lover of black
This is because the argument of # (and ##) is not subject to macro
expansion. But, as the example above show, you normally want macro
expansion to occur, so you have to add a helper macro (TOSTR and
PIKE_CONCAT).
But in the case of GET_VAL, where we use true and false as arguments,
we don't want to macro-expand them. At least not when <stdbool.h> is
included. And we never need to expand them -- there is no need to
support something convoluted like:
#define TRUTH_VALUE false
GET_VAL(TRUTH_VALUE)
#undef TRUTH_VALUE
#define TRUTH_VALUE true
GET_VAL(TRUTH_VALUE)
#undef TRUTH_VALUE
(We are trying to use jemalloc with Pike, and for some reason
including the jemalloc header file also seems to include <stdbool.h>,
so we ran into this issue.)