Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save original value of C++ preprocessor macro

I want to save the original textual value of a macro so that I can then redefine the macro and still refer to the original value. My use case involves a macro to a macro, so that the value I am trying to save is still itself a macro. I have a small example of attempts in an online interpreter, which I am copying the code from here. I am aware that other SO questions discuss similar ideas but I have not found anything that covers my use case.

#include <stdio.h>

#define STR(X) (#X)

#define GLOBAL_INT (3)

// I AM TRYING TO SAVE THE TEXTUAL MACRO CONTENT "GLOBAL_INT" (WITHOUT THE QUOTES)
//  IN ANOTHER MACRO SO THAT I CAN UNDEFINE GIM AND STILL REFER TO GLOBAL_INT

#define GIM (GLOBAL_INT)

#define GIM_SAVE (GIM)
#define GIM_SAVE_STR (STR(GIM))
#define STR_GIM_SAVE (STR(GIM_SAVE))
const char *strGimSave = STR(GIM_SAVE);
const char *gimSaveStr = GIM_SAVE_STR;
const char *strGimSaveM = STR_GIM_SAVE;
const char *gimStr = STR(GIM);

#undef GIM

int main(int argc, char *argv[])
{
    printf("strGimSave=%s\n", strGimSave);
    printf("gimSaveStr=%s\n", gimSaveStr);
    printf("strGimSaveM=%s\n", strGimSaveM);
    printf("gimStr=%s\n", gimStr);

    const char *gim_save = STR(GIM_SAVE);
    const char *gim_save_str = GIM_SAVE_STR;
    const char *str_gim_save = STR_GIM_SAVE;
    printf("\ngim_save=%s\n", gim_save);
    printf("gim_save_str=%s\n", gim_save_str);
    printf("str_gim_save=%s\n", str_gim_save);

    return 0;
}

Same code in online interpreter

Edit: I am trying to output "GLOBAL_INT" in the above code. The above code outputs:

strGimSave=GIM_SAVE
gimSaveStr=GIM
strGimSaveM=GIM_SAVE
gimStr=GIM

gim_save=GIM_SAVE
gim_save_str=GIM
str_gim_save=GIM_SAVE
like image 696
taz Avatar asked Oct 23 '25 13:10

taz


1 Answers

It is not possible. C/C++ preprocessor expands macros on evaluation only. There is no way to tell it to define macro to expanded result of another.

That said, the first part of your sample would actually do what you want if you used correct definition of STR:

#include <stdio.h>

// HERE, extra level of indirection
#define STR2(X) (#X)
#define STR(X) STR2(X)

#define GLOBAL_INT (3)

#define GIM (GLOBAL_INT)

#define GIM_SAVE (GIM)
#define GIM_SAVE_STR (STR(GIM))
#define STR_GIM_SAVE (STR(GIM_SAVE))
const char *strGimSave = STR(GIM_SAVE);
const char *gimSaveStr = GIM_SAVE_STR;
const char *strGimSaveM = STR_GIM_SAVE;
const char *gimStr = STR(GIM);

#undef GIM

int main(int argc, char *argv[])
{
    printf("strGimSave=%s\n", strGimSave);
    printf("gimSaveStr=%s\n", gimSaveStr);
    printf("strGimSaveM=%s\n", strGimSaveM);
    printf("gimStr=%s\n", gimStr);

    const char *gim_save = STR(GIM_SAVE);
    const char *gim_save_str = GIM_SAVE_STR;
    const char *str_gim_save = STR_GIM_SAVE;
    printf("\ngim_save=%s\n", gim_save);
    printf("gim_save_str=%s\n", gim_save_str);
    printf("str_gim_save=%s\n", str_gim_save);

    return 0;
}

Now produces

strGimSave=(((3)))
gimSaveStr=((3))
strGimSaveM=(((3)))
gimStr=((3))

gim_save=(GIM)
gim_save_str=GIM
str_gim_save=(GIM)

(See live on coliru)

As you see once you #undef GIM the macros stop expanding to "3", but the string constants created while GIM was defined retain the value. With all the parenthesis that you've put into those macros.

like image 104
Jan Hudec Avatar answered Oct 25 '25 03:10

Jan Hudec