Подтвердить что ты не робот

Являются ли пустые макрокоманды законными в С++ 11?

Я иногда умышленно игнорирую макро аргументы. Например, для функционально-подобного макроса, такого как

#define MY_MACRO(A, B, C)  ...

Я бы назвал его как:

MY_MACRO(, bar, baz)

Есть еще 3 аргумента. это просто, что первый из них "пуст". Этот вопрос касается не переменных массивов.

Когда я это делаю, я получаю предупреждения от g++ при компиляции с -ansi (aka -std=c++98), но не тогда, когда я использую -std=c++0x. Означает ли это, что пустые макросы являются законными в новом стандарте С++?

Это весь мой вопрос, но предвосхищая "зачем вы хотите?". ответ, вот пример. Мне нравится хранить файлы .h, незагроможденные органами функций, но внедрение простых аксессуаров за пределами файла .h утомительно. Поэтому я написал следующий макрос:

#define IMPLEMENT_ACCESSORS(TEMPLATE_DECL, RETURN_TYPE, CLASS, FUNCTION, MEMBER) \
  TEMPLATE_DECL                                                         \
  inline RETURN_TYPE* CLASS::Mutable##FUNCTION() {                      \
    return &MEMBER;                                                     \
  }                                                                     \
                                                                        \
  TEMPLATE_DECL                                                         \
  inline const RETURN_TYPE& CLASS::FUNCTION() const {                   \
    return MEMBER;                                                      \
  }

Вот как я буду использовать его для шаблона класса, содержащего int, называемый int_:

IMPLEMENT_ACCESSORS(template<typename T>, int, MyTemplate<T>, Int, int_)

Для класса, отличного от шаблона, мне не нужен template<typename T>, поэтому я опускаю этот аргумент макроса:

IMPLEMENT_ACCESORS(, int, MyClass, Int, int_)
4b9b3361

Ответ 1

Если я правильно понимаю, пустой аргумент макроса разрешен с C99 и С++ 0x (11).
В C99 6.10.3/4 говорится:

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

и С++ N3290 16.3/4 имеет тот же оператор, в то время как С++ 03 16.3/10 упоминает:

... любой аргумент не содержит токенов предварительной обработки, поведение undefined.

Я думаю, что пустой аргумент подпадает под аргументы представления, состоящие из нет токенов предварительной обработки.
Кроме того, 6.10.3 в Обосновании для международных стандартных языков программирования C rev. 5,10  говорит:

Новая функция C99: вызовы макросов, подобные функции, также могут теперь имеют пустые аргументы, т.е. аргумент может состоять из токены предварительной обработки.

Ответ 2

Да. Соответствующий бит равен 16,3/11

Последовательность токенов предварительной обработки, ограниченных внешними совпадающие круглые скобки образуют список аргументов для функции макро. Отдельные аргументы в списке разделяются запятой токены предварительной обработки.

Нет требования, чтобы один аргумент соответствовал точно одному токену. На самом деле в следующем разделе дается понять, что для каждого аргумента может быть более одного токена:

Перед заменой каждого токена предварительной обработки аргументов полностью сменили макрос, как если бы они сформировали остальную часть файл предварительной обработки

В вашем случае один аргумент соответствует нулевым токенам. Это не вызывает никаких противоречий.

[править] Это было изменено N1566, чтобы привести С++ 11 в соответствие с C99.

Ответ 3

Когда я делаю это, я обычно помещаю комментарий вместо аргумента.

Поместите макрос, который будет расширен до пустой строки.

#define NOARG
...
MY_MACRO(/*Ignore this Param*/ NOARG, bar, baz)

PS. Я не получил предупреждения с g++ с флагом -std = С++ 98 или без него.

  • g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
  • g++ (Apple Inc. build 5666) 4.2.1