根据 c++ 标准,当 pushing/popping 宏定义中的宏时,行为是什么

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

我刚才回答了一个关于附加到 C 宏的问题 在 Can I append to a preprocessor macro?

正如答案所说,以下内容在 clang 和 g++ 中都有效,但在 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

虽然这看起来确实有效,但我想知道这是否恰好适用于 gcc 和 clang,但 msvc 也是(或仅)正确的,或者如果它们表现出的行为是强制的行为 由语言规范。如果 C 和 C++ 有所不同,我对它们都感兴趣(主要是对 最新版本,写作时的 C18 和 C++17)

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

在 C 和 C++ 中,#pragma_Pragma 的结果是实现定义的,因此标准不管理它们的行为。参见 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.

6.10.9涵盖_Pragma

和最新的 C++ 草案 [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.

另见[cpp.pragma.op]

None gcc or MSVC 中这些 pragam 的文档似乎非常详细。所以他们并没有提供太多的指导。