0

I answered a question a while ago about appending to C macros at Can I append to a preprocessor macro?

As the answer says, the following works in both clang and g++, but not in msvc

#define pushfoo _Pragma("push_macro(\"foo\")") //for convenience
#define popfoo _Pragma("pop_macro(\"foo\")") //I tried __pragma and __Pragma for msvc as well

#define foo 1

pushfoo                           //push the old value
#undef foo                        //so you don't get a warning on the next line
#define foo popfoo foo , 2        //append to the previous value of foo

pushfoo
#undef foo
#define foo popfoo foo , 3

pushfoo
#undef foo
#define foo popfoo foo , 4


foo //this whole list will expand to something like popfoo foo popfoo foo popfoo foo , 4
    //which will in turn expand to 1 , 2 , 3 , 4

foo //the second time this will expand to just 1

While this does seem to work, I want to know if this is just something that happens to work out for gcc and clang, but msvc is also (or only) correct, or if the behavior they exhibit is the behavior mandated by the language specification. I am interested in both C and C++ if they differ (mostly interested in the newest editions, C18 and C++17 at the time of writing)

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
rtpax
  • 1,687
  • 1
  • 18
  • 32
  • 8
    Any time you see the term `pragma` it usually means what comes next is non-Standard. It might appear in multiple toolchains, but you can't expect it in all or without differences. – user4581301 Sep 05 '18 at 18:36
  • 1
    Macro push and pop is not standard C++. – Cheers and hth. - Alf Sep 05 '18 at 18:37
  • 3
    Try to find solutions to problems that *do NOT* involve macros. – Jesper Juhl Sep 05 '18 at 18:38
  • @user4581301 I see, so even though `_Pragma` keyword is standardized, how the program interprets the contents is not? – rtpax Sep 05 '18 at 18:43
  • 3
    Documentation for `pragma` and `_Pragma`: https://en.cppreference.com/w/cpp/preprocessor/impl Key concepts: *The ISO C++ language standard does not require the compilers to support any pragmas* and *Any pragma that is not recognized is ignored.* – user4581301 Sep 05 '18 at 18:44
  • 2
    While macros have their application (less in C++ than in C), this looks like you are already past the gate to macro-hell. Whatever you try to accomplish: stop here, two steps back and sleep over it. Then rethink your system architecture. – too honest for this site Sep 05 '18 at 19:30
  • 3
    @toohonestforthissite funnily enough, the document I have with that code is called `macro_hell.cpp` – rtpax Sep 05 '18 at 20:34

1 Answers1

2

What is the behavior when pushing/popping a macro inside that macro definition according to c++ standard?

In both the C and C++ the result of #pragma and _Pragma are implementation defined, so the standard does not govern their behavior. See C11 6.10.6p1:

A preprocessing directive of the form

 # pragma pp-tokensopt new-line

where the preprocessing token STDC does not immediately follow pragma in the directive (prior to any macro replacement)174) causes the implementation to behave in an implementation-defined manner. The behavior might cause translation to fail or cause the translator or the resulting program to behave in a non-conforming manner. Any such pragma that is not recognized by the implementation is ignored.

and 6.10.9 covers _Pragma.

and the latest C++ draft [cpp.pragma]:

A preprocessing directive of the form

# pragma pp-tokensopt new-line

causes the implementation to behave in an implementation-defined manner.* The behavior might cause translation to fail or cause the translator or the resulting program to behave in a non-conforming manner. Any pragma that is not recognized by the implementation is ignored.

and also see [cpp.pragma.op]

None of the documentation for these pragams from gcc or MSVC seem to be very detailed. So they don't offer much in the way of guidance.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740