I can't really answer your question, other than to point out there are several rather arcane artifacts that go along with the manner and sequence in which pre-processor macros are parsed and expanded. It is (mostly) explained in the gcc pre-processor documentation, but will probably take a good bit of reading (and a bit of hair-pulling) to get to the answer you want.
FWIW - IIRC, #x creates a quoted string consisting of the string literal value of x. I have used this to create an array of strings from the members of an enum. For example, I believe if x evalutes to the literal string XYZZY, then #x will evaluate to the literal string "XYZZY", including the quotes.
Regards,
Ray L.
The comment confused you due to it being poorly written: not "extension" but "expansion".
The two tier method allows the argument to undergo macro expansion before stringification. So:
#define FOO 123
DEBSHOW_(FOO) == "FOO"
DEBSHOW(FOO) == "123"
Delta_G:
Why did they need to double-define that DEBSHOW macro like that?
In this particular case I believe it is superfluous.
I tried some experiments and it looks like the expansion of DEBSHOW_(x) and DEBSHOW(x) are identical.
#define DEBUG_SERIAL Serial
#define DEBPMACRO(x) DEBUG_SERIAL.println(F("D macro " #x " is " DEBSHOW_(x) " which is " DEBSHOW(x) ));
// add a layer of indirection to allow macro extension
#define DEBSHOW(x) DEBSHOW_(x)
#define DEBSHOW_(x) #x
#define MACRO_1 1
#define MACRO_MACRO_1 MACRO_1
#define MACRO_2 (MACRO_1+MACRO_1)
const char array[] = "Test";
void setup()
{
Serial.begin(115200);
while (!Serial);
DEBPMACRO(MACRO_1)
DEBPMACRO(MACRO_MACRO_1)
DEBPMACRO(MACRO_2)
DEBPMACRO(array)
}
void loop() {}
Results:
D macro MACRO_1 is 1 which is 1
D macro MACRO_MACRO_1 is 1 which is 1
D macro MACRO_2 is (1+1) which is (1+1)
D macro array is array which is array
I suspect the entire point of the DEBSHOW() macro is to ensure only a FULLY expanded argument can get passed to the "#" operator in the DEBSHOW_() macro.
Try defining x as a string with spaces in it. My guess is the result may not be what you might expect.
Regards,
Ray L.
johnwasser:
I tried some experiments and it looks like the expansion of DEBSHOW_(x) and DEBSHOW(x) are identical.
You are forgetting that the DEBPMACRO itself is an additional layer of indirection.
Just print MACRO_MACRO_1 using both of DEBSHOW_* without using DEBPMACRO.
Yup. Superfluous...
#define MACROA 1 + 2 + 3 + a + x
#define MACROB MACROA + 42
#define DEBUG_SERIAL Serial
# define DEBPMACRO(x) DEBUG_SERIAL.println(F("D macro " #x " is " DEBSHOW(x)));
// add a layer of indirection to allow macro extension
//#define DEBSHOW(x) DEBSHOW_(x)
//#define DEBSHOW_(x) #x
#define DEBSHOW(x) #x
void setup(void)
{
Serial.begin( 250000 );
DEBPMACRO(MACROA);
DEBPMACRO(MACROB);
}
void loop(void)
{
}
D macro MACROA is 1 + 2 + 3 + a + x
D macro MACROB is 1 + 2 + 3 + a + x + 42
Superfluous if you assume that the Delta_G's example is complete; but those are just 3 lines of code - there could be other lines where DEBSHOW() is used outside of an enclosing macro context.