Допустимы ли пустые макро-аргументы в C ++ 11? - PullRequest
25 голосов
/ 05 октября 2011

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

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

Я мог бы назвать это как:

MY_MACRO(, bar, baz)

Технически есть еще 3 аргумента; просто первый «пустой». Этот вопрос не о вариадических макросах.

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

Вот и весь мой вопрос, но предвосхищение "почему ты хочешь?" ответ, вот пример. Мне нравится хранить файлы .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_)

Ответы [ 3 ]

14 голосов
/ 06 октября 2011

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

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

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

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

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

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

8 голосов
/ 06 октября 2011

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

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

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

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

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

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

4 голосов
/ 05 октября 2011

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

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

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

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

  • g ++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
  • g ++ (Apple Inc. build 5666) 4.2.1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...