Я часто использую строковые литеральные таблицы в своем C-коде. Эти таблицы выглядят примерно так:
static const char* const stateNames[STATE_AMOUNT] =
{
"Init state",
"Run state",
"Pause state",
"Error state",
};
Проблема с приведенным выше кодом заключается в том, что если таблица становится длиннее и изменяется в процессе разработки, я время от времени забываю запятую. Код компилируется без проблем с пропущенной запятой, но моя программа завершается сбоем, поскольку последняя строка установлена в NULL
. Я использовал компиляторы MinGW и Keil для проверки.
Есть ли способ генерировать предупреждение компилятора для моей инициализации, если запятая отсутствует?
c
initialization
Джонни Шуберт
источник
источник
Ответы:
Обтекание каждой
const char*
пары в скобках должно решить проблему, как показано в следующем фрагменте:Если вы забудете запятую, вы получите ошибку компиляции, похожую на:
error: called object is not a function or function pointer
LIVE DEMO
Обратите внимание, что если вы забудете запятую, то на самом деле происходит то, что C фактически объединит две (или более) строки до следующей запятой или до конца массива. Например, допустим, вы забыли запятую, как показано ниже:
Вот что
gcc-9.2
генерирует (другие компиляторы генерируют похожий код):Понятно, что последние три строки объединены, и массив не соответствует ожидаемой длине.
источник
Вы можете позволить компилятору считать массив и генерировать сообщение об ошибке, если неожиданный результат:
Посмотрите эту ветку для идей для реализации,
_Static_assert
если ваш компилятор очень старый и не поддерживает его.В качестве бонуса это также может помочь, когда вы добавляете новые состояния, но забыли обновить таблицу строк. Но вы можете захотеть взглянуть и на X Macros.
источник
Я всегда использовал ссылку на явно размерный массив, чтобы решить эту проблему.
http://coliru.stacked-crooked.com/a/593fc2eac80782a6
источник
Это не поможет компилятору помочь вам, но я нахожу, что его написание, как показано ниже, облегчает людям не ставить запятую:
источник