Search code examples
c++cvisual-c++preprocessor

Are pragma push/pop_macro directive stacks unique to each macro?


Microsoft provides the following example:

// pragma_directives_pop_macro.cpp
// compile with: /W1
#include <stdio.h>
#define X 1
#define Y 2

int main() {
   printf("%d",X);
   printf(" %d",Y);
   #define Y 3   // C4005
   #pragma push_macro("Y")
   #pragma push_macro("X")
   printf(" %d",X);
   #define X 2   // C4005
   printf(" %d",X);
   #pragma pop_macro("X")
   printf(" %d",X);
   #pragma pop_macro("Y")
   printf(" %d",Y);
}

which outputs: 1 2 1 2 1 3

Is there a separate stack for macro "Y" and macro "X", or do they use the same stack for all macros?


Solution

  • Each macro has its own stack. As the documentation you link to says, push_macro “Saves the value of the macro-name macro on the top of the stack for this macro,” and pop_macro “Sets the value of the macro-name macro to the value on the top of the stack for this macro.”

    We can confirm this interpretation with code that pops X and Y not in last-in-first-out-order yet recovers the values originally pushed for X and Y respectively:

    #include <stdio.h>
    
    int main(void)
    {
        #define X "X0" 
        #define Y "Y0"
        printf("X=%s.\n", X);
        printf("Y=%s.\n", Y);
        #pragma push_macro("X")
        printf("Pushed X.\n");
        #pragma push_macro("Y")
        printf("Pushed Y.\n");
        #undef X
        #undef Y
        #define X "X1"
        #define Y "Y1"
        printf("X=%s.\n", X);
        printf("Y=%s.\n", Y);
        #pragma pop_macro("X")
        printf("Popped X.\n");
        #pragma pop_macro("Y")
        printf("Popped Y.\n");
        printf("X=%s.\n", X);
        printf("Y=%s.\n", Y);
    }
    

    which prints:

    X=X0.
    Y=Y0.
    Pushed X.
    Pushed Y.
    X=X1.
    Y=Y1.
    Popped X.
    Popped Y.
    X=X0.
    Y=Y0.