不久前,我回答了一个关于在我可以附加到预处理宏吗?上向C宏附加内容的问题
正如答案所述,以下内容在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感兴趣)
发布于 2018-09-05 19:39:14
根据c++标准,在该宏定义中推送/弹出宏时,会发生什么行为?
在C和C++中,#pragma和_Pragma的结果都是被定义的,因此标准不规范它们的行为。见C11 6.10.6p1
fail杂注pp-tokensopt新行的预处理指令,其中预处理令牌STDC不会立即跟随指令中的杂注(在任何宏替换之前)174)会导致实现以实现定义的方式运行。行为可能导致翻译失败或导致翻译程序或结果程序以不一致的方式运行。任何未被实现识别的此类实用程序都将被忽略。
6.10.9覆盖了_Pragma。
以及最新的C++草案[cpp.pragma]
fail实用化pp-tokensopt新行的预处理指令导致实现以实现定义的方式运行。*行为可能导致翻译失败或导致翻译程序或结果程序以不一致的方式运行。未被实现识别的任何实用程序都将被忽略。
也见[cpp.pragma.op]
https://stackoverflow.com/questions/52191496
复制相似问题