c++ макросы Неправильно ли добавлять директивы препроцессора в функционально-подобный макрос?



аргументы макросов (2)

Язык C оставляет это как неопределенное поведение в 6.10.3 Замена макроса, ¶11 :

Если в списке аргументов есть последовательности токенов предварительной обработки, которые в противном случае выступали бы в качестве предпроцессорных директив, поведение не определено.

Так что действительно неправильно это делать.

GCC и, возможно, другие популярные компиляторы не поймают его, поэтому, вероятно, многие пользователи этого языка не знают. Я столкнулся с этим, когда некоторые из моего кода не удалось скомпилировать на PCC (и быстро исправили ошибку в моем коде).

Обновление: PJTraill задал в комментариях случай, когда было бы «вводящим в заблуждение или бессмысленным» иметь директивы препроцессора внутри макрорасширения. Вот очевидное:

    foo(a, b,
#ifdef BAR
        c);
#else
        d);
#endif

Я не уверен, было бы правдоподобным для языка, чтобы указать, что сбалансированные условия препроцессора внутри расширения макросов в порядке, но я думаю, что у вас возникнут проблемы с неопределенностью в том порядке, в котором они должны обрабатываться.

Я знаю, что мой вопрос похож на этот или на этот , но я считаю, что это не совсем то же самое, и, более того, у второго ответа нет ответа, я решил спросить, правильно ли добавлять директивы препроцессора, когда вызывается функционально-подобный макрос?

В моем случае у меня есть функциональный макрос:

#define FUNC_MACRO(a, b)  // do something with the variables

и где-то в коде я вызываю его с определенной разницей, если определен какой-то другой макрос:

// ...
FUNC_MACRO(aVal
#ifdef ANOTHER_MACRO
                + offset
#endif // ANOTHER_MACRO
           , bVal);
// ...

Я тестировал на своей машине (linux, gcc 4.8), и он работал нормально (с директивами препроцессора и без них и с и без ANOTHER_MACRO), но безопасно ли это сделать?

Я прочитал абзац 16.3 / 9 из ответа на первый подобный вопрос, но верно ли это для моего дела?


Answer #1

Выполните следующее вместо этого?

#ifdef ANOTHER_MACRO
FUNC_MACRO(aVal + offset, bVal);
#else
FUNC_MACRO(aVal, bVal);
#endif

РЕДАКТИРОВАТЬ: рассмотрение проблемы, вызванной комментариями; Я не знаю, является ли метод OP специально неправильным (я думаю, что другие ответы охватывают это). Тем не менее, кратковременность и ясность - это два аспекта, которые считаются очень важными при кодировании C.

Поэтому я бы предпочел найти лучшие способы достижения того, что, по-видимому, пытается сделать ОП, слегка переосмыслив ситуацию, такую, какую я предложил выше. Я думаю, что OP, возможно, использовал тривиализованный пример, но обычно я нахожусь в большинстве ситуаций C, если что-то становится чрезмерно сложным или пытается что-то сделать, это не похоже на то, что язык должен позволять, тогда есть лучшие способы достичь того, что необходимо ,





macros