Универсальное решение «ISO C99 требует как минимум один аргумент для«… »в вариационном макросе» - PullRequest
0 голосов
/ 08 декабря 2018

Что такое универсальный способ разрешения

предупреждение: 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

, который подвержен ошибкам.

...