Являются ли пустые макрокоманды законными в С++ 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_)
Ответы
Ответ 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