not-a-user
not-a-user

Reputation: 4327

How to get the definition of a macro as a string literal?

Say in a header, which I do not want to read myself but which I do include, I have

#define A B
#define B C

Now

#define STR(name) # name

defines a macro that gives me the name of any macro as a string, and

#define EXP_STR(name) STR(name)

defines a macro that gives me the full expansion of any macro as a string. So

cout << STR(A) << EXP_STR(A) << endl;

will print AC.

Is there any way to get "B" from A using some macros?

Upvotes: 11

Views: 242

Answers (2)

MD XF
MD XF

Reputation: 8129

Yeah, it's possible. You just have to use a couple of cheats.

  • #undef B before #define EXP_STR
  • Use a few more levels of indirection

For example:

#define A B
#define B C

#define _TEMP_VAR B    // so that it can be redefined later
#undef B               // so that EXP_STR(A) will return "B"

#define EXP_STR__(x) (x)
#define EXP_STR_(x)  EXP_STR__(#x)
#define EXP_STR(x)   EXP_STR_(x)

#define STR(x) # x

#define B _TEMP_VAR    // now you can still access A normally, defined to B (defined to C)

A test program to prove it:

#include <stdio.h>

int main(void)
{
    printf( "EXP_STR(A) = %s\n", EXP_STR(A) );
    printf( "STR(A)     = %s\n", STR(A) );
}

Output:

EXP_STR(A) = B
STR(A)     = A

Upvotes: 0

Iharob Al Asimi
Iharob Al Asimi

Reputation: 53016

Since you can write

#define B C
#define A B

#define STR(name) # name
#define EXP_STR(name) STR(name)

and the

cout << STR(A) << EXP_STR(A) << endl;

will output exaclty the same, it means that it's not possible.

When you do this

#define A B

and then

#define B C

now this means that A will be substituted by C and not B, so there will be no way to do it because when the cout line is reached the preprocessor had already substituted A by C.

So the short answer is, it's not possible because the preprocessor would have replaced A with C before the file is compiled.

Upvotes: 1

Related Questions