Законно ли вызывать вариадный макрос M
без аргументов для его параметра variadic?
Соответствующая стандартная цитата [Cpp.replace] / 4:
Если список идентификаторов в определении макроса не заканчивается многоточием, число аргументов (включая те аргументы, которые не содержат токены предварительной обработки) при вызове функционально-подобного макроса должно равняться количеству параметров в определении макроса. В противном случае в вызове должно быть больше аргументов, чем параметров в определении макроса (исключая
...
). Там должно существовать)
маркер предварительной обработки, завершающий вызов.
Для случая без невариантных параметров вызов в виде M()
должен быть допустимым, поскольку вызов имеет один аргумент (состоящий из токенов предварительной обработки). Таким образом, есть еще один аргумент, чем невариантные параметры.
Для случая с одним невариантным параметром, должен ли быть трейлинг ,
как в M(1,)
ввести аргумент, состоящий из жетонов предварительной обработки для параметра вариации? В противном случае количество аргументов будет равно количеству невариантных параметров. т.е.
#define variadic(x,...) #__VA_ARGS__
variadic(1,) // 2 arguments: ok
variadic(1) // 1 argument: wrong?
И то и другое лязг а также НКУ, однако примите следующий тестовый пример:
#include <iostream>
#define variadic(x,...) #__VA_ARGS__
int main()
{
std::cout << "'" variadic(1) "'" << std::endl;
}
и производить в качестве выхода:
''
Это нестандартное поведение?
В противном случае в вызове должно быть больше аргументов, чем параметров в определении макроса (исключая …).
Этот отрывок из стандарта показывает, что ваш код не должен быть действительным: у вас есть один параметр плюс многоточие. Если мы следуем части стандарта выше, у вас должно быть как минимум два аргумента. Когда ты пишешь varidadic(1)
Вы просто предоставляете один аргумент. Ваш код недействителен.
Кстати, Clang выдает предупреждение:
main.cpp:7:32: warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu]
std::cout << "'" variadic(1) "'" << std::endl;
И GCC также выдает предупреждение:
main.cpp:7:32: warning: ISO C99 requires rest arguments to be used [enabled by default]
std::cout << "'" variadic(1) "'" << std::endl;
Поскольку это может беспокоить программиста, и поскольку намерение программиста легко угадать, они оба считают variadic(1)
эквивалентно variadic(1,)
,
Других решений пока нет …