Что такое универсальный способ разрешения
предупреждение: ISO C ++ 11 требует как минимум один аргумент для "..." в макросе с переменным числом
предупреждение, введенное флагом -pedantic
для gcc?
Рассмотрим следующий пример
#define FUNCTION_DECL(ret, name, ...) ret name(__VA_ARGS__)
FUNCTION_DECL(int, foo, int bar, int quax)
{
return bar + quax;
}
FUNCTION_DECL(void, no_args)
{
}
Расширение no_args
macro приводит к ошибке выше.
Примером решения этой проблемы было бы иметь два макроса и затем простой трюк с перегрузкой
#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, NAME, ...) NAME
#define METHOD_DECL2(ret, name) ret name()
#define METHOD_DECL3(ret, name, ...) ret name(__VA_ARGS__)
#define METHOD_DECL(...) GET_MACRO(__VA_ARGS__, METHOD_DECL3, METHOD_DECL3, METHOD_DECL3, METHOD_DECL3, METHOD_DECL3, METHOD_DECL3, METHOD_DECL3, METHOD_DECL2)(__VA_ARGS__)
Тогда METHOD_DECL(void, no_args)
больше не вызывает ошибку.
К сожалению,это не работает в MSVC2017, но исправлено в последнем превью MSVC2019 .
И это решение несколько неуклюже.Я пытался придумать другое решение, что-то вроде
#define EXTRACT_FIRST(_1, ...) _1
#define OMIT_FIRST(_1, ...) __VA_ARGS__
#define METHOD_DECL(ret, ...) ret EXTRACT_FIRST(__VA_ARGS__) OMIT_FIRST(__VA_ARGS__)
Но это только переместило проблему, так как теперь OMIT_FIRST
вызывает эту ошибку
РЕДАКТИРОВАТЬ:
Я пытаюсь сделать следующее:
У меня есть функция в ассемблере AVR (микроконтроллер)
delay_37us:
ldi r16, 227
delay_592c_aw:
dec r16
brne delay_592c_aw
nop
nop
ret
Этот активный ожидает 592 тактов (что составляет 37us для процессора 16 МГц)
Чтобы вызвать эту функцию в C, я должен отметить ее как .global
, а также предоставить объявление C для такой функции.Чтобы упростить объявление такой функции, я бы использовал такой макрос
FUNCTION_DECL(void, delay_37us);
, который был бы определен как
#ifdef __ASSEMBLER__
#define FUNCTION_DECL(ret, name, ...) .global name
#else
#define FUNCTION_DECL(ret, name, ...) ret name(__VA_ARGS__)
#endif
, чтобы я мог использовать один заголовочный файл для C иКАК М.В настоящее время я использую один заголовочный файл со следующим содержимым
#ifdef __ASSEMBLER__
.global delay_37us
.global delay_ms
.global delay_1s
#else
void delay_37us();
void delay_ms(unsigned char);
void delay_1s();
#endif
, который подвержен ошибкам.