Каково поведение при нажатии / извлечении макроса внутри определения макроса в соответствии со стандартом c ++ - PullRequest
0 голосов
/ 05 сентября 2018

Я недавно ответил на вопрос о добавлении макросов в 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 и лязг, но msvc также (или только) правильный, или если поведение, которое они демонстрируют, является обязательным поведением по спецификации языка. Я заинтересован в C и C ++, если они различаются (в основном интересует новейшие издания, C18 и C ++ 17 на момент написания)

1 Ответ

0 голосов
/ 05 сентября 2018

Каково поведение при нажатии / извлечении макроса внутри определения макроса в соответствии со стандартом c ++?

И в C, и в C ++ результат #pragma и _Pragma определяется реализацией, поэтому стандарт не регулирует их поведение. См. C11 6.10.6p1 :

Директива предварительной обработки вида

 # pragma pp-tokensopt new-line

, где токен предварительной обработки STDC не следует сразу же за прагмой в директиве (до любой замены макроса) 174) заставляет реализацию вести себя в соответствии с реализацией. Такое поведение может привести к сбою преобразования или заставить переводчик или результирующую программу вести себя несоответствующим образом. Любая такая прагма, которая не распознается реализацией, игнорируется.

и 6.10.9 обложки _Pragma.

и последняя версия C ++ [cpp.pragma] :

Директива предварительной обработки вида

# pragma pp-tokensopt new-line

заставляет реализацию вести себя определенным для реализации способом. * Такое поведение может привести к сбою перевода или к тому, что переводчик или получающаяся программа будут вести себя не соответствующим образом. Любая прагма, которая не распознается реализацией, игнорируется.

, а также см. [cpp.pragma.op]

Ни одна из документации по этим прагамам из gcc или MSVC не представляется очень подробной. Таким образом, они не предлагают много в качестве руководства.

...