Как сделать запятую внутри фигурных скобок внутри аргумента макроса, если круглые скобки вызывают синтаксическую ошибку?

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

struct string_holder {
    const char *string;
};
struct string_array_holder {
    struct string_holder *holders;
};
#define DEFINE_STRING_ARRAY_HOLDER(name, values) \
    static struct string_holder name##__array[] = values; \
    static struct string_array_holder name = { name##__array }
#define WRAP_STRING(string) { string }

Он отлично работает, когда вы используете его для объявления массива с один элемент:

DEFINE_STRING_ARRAY_HOLDER(my_string_array_holder, {
    WRAP_STRING("my string")
});

Но когда я использую несколько элементов:

DEFINE_STRING_ARRAY_HOLDER(my_string_array_holder, {
    WRAP_STRING("hello"),
    WRAP_STRING("world")
});

, я получаю эту ошибку:

ошибка: слишком много аргументов предоставлено для вызова макроса, подобного функции

Таким образом, он интерпретирует запятую в фигурных скобках в качестве разделителя аргументов. Я следую совету этого вопроса и заключаю в круглые скобки проблемный аргумент:

DEFINE_STRING_ARRAY_HOLDER(my_string_array_holder, ({
    WRAP_STRING("hello"),
    WRAP_STRING("world")
}));

Теперь, когда я пытаюсь его скомпилировать, он интерпретирует ({...}) как выражение оператора и жалуется:

предупреждение: использование расширения выражения оператора GNU
(куча синтаксических ошибок, возникающих из-за его интерпретации как выражения оператора)
ошибка: выражение оператора не разрешено в области файла

Как я могу:

  • Использовать макрос без ошибок (предпочтительно), или
  • Переписать макрос [s] для работы в этих обстоятельствах?

14
задан Community 23 May 2017 в 12:33
поделиться