Требуется ли последняя запятая в C enum?

Требуется ли последняя запятая в декларации C enum?

то есть. является запятой после VAL3?

enum{Val1, Val2, Val3,} someEnum;

Есть ли какие-либо побочные эффекты, связанные с его выходом/выходом

Спасибо

Ответ 1

Это не требуется. В разделе 6.7.2.2 для C99 указан синтаксис как:

enum-specifier:
    enum identifieropt { enumerator-list }
    enum identifieropt { enumerator-list , }
    enum identifier
enumerator-list:
    enumerator
    enumerator-list , enumerator
enumerator:
    enumeration-constant
    enumeration-constant = constant-expression

Обратите внимание на первые две формы enum-specifier, один с конечной запятой и один без.

Одно из преимуществ, которое я видел, это использовать такие вещи, как:

enum {
    Val1,
    Val2,
    Val3,
} someEnum;

где, если вы хотите добавить (например) Val4 и Val5, вы просто скопируете и вставьте строку Val3, не беспокоясь о настройке запятых.

И, как указано в комментарии, также может быть упрощено автоматическое создание генераторов кода, так что им не нужно иметь специальную обработку для конечного значения. Они могут просто выводить каждое значение, за которым следует запятая.

Это можно сравнить с часто просматриваемым SQL:

select fld1, fld2 from tbl where 1=1 and fld1 > 8

В этом случае where 1=1 существует только так, что вам не нужно ставить where до вашего первого предложения и and перед каждым последующим. Вы можете просто полагаться на то, что where уже существует и просто используйте and для всех добавленных вами.

Некоторые люди могут подумать, что этот запах лени, и они правы, но это не обязательно плохо: -)

Любой порядочный оптимизатор запросов СУБД должен иметь возможность отключить постоянное предложение, подобное этому, перед тем как перейти к таблицам базы данных.

Ответ 2

Как и все остальные, запятая не требуется. Но это новое в C99 (не разрешено в C89) и будет разрешено в следующей версии С++ тоже.

Еще одно обоснование состоит в том, чтобы сделать разницу между перечислителем длины и нормальным перечислителем:

enum Items {
    A,
    B,
    C,
    LENGTH
};

Теперь вы можете поместить в свое руководство по кодированию, что последний элемент в вашем перечислении должен иметь запятую, но не если это элемент "Длина", который просто указывает, сколько предметов есть.

Это также помогает автоматически генерировать элементы (используя макросы/препроцессоры), как объясняют другие ответы.

Ответ 3

В стандарте C89 последняя запятая не разрешена. Полная остановка.

Это было общее расширение, позволяющее это; в частности, он был поддержан GCC, но стандарт прямо запретил его.

В стандарте C99 допускается последняя запятая для симметрии с инициализаторами массива и структуры, которые всегда позволяли конечную запятую в последнем элементе.

6.7.2.2 Спецификаторы перечисления

Синтаксис

   enum-specifier:
            enum identifieropt { enumerator-list }
            enum identifieropt { enumerator-list , }
            enum identifier

Основным преимуществом разрешающей запятой является то, что она позволяет проще генерировать компьютерный код (C source) - вам не нужно писать специальный код для последнего (или, может быть, первого) элемента в списке инициализаторов, Следовательно, такие программы, как Yacc и Lex, чтобы назвать только два, могут быть немного проще.

Ответ 4

Нет, это не требуется. Причина в том, что это облегчает для целей кода вырезания и вставки, если вам не нужно беспокоиться о том, должна ли запятая быть там или нет.

Ответ 5

Нет, это не требуется - на самом деле я бы сказал, что у него плохой стиль.

Ответ 6

Как уже говорилось, это не требуется. Причина, по которой поддерживается конечная запятая, заключается в том, что она (при условии, что элементы выложены одна на линию), позволяет вам упорядочить порядок элементов в перечислении с помощью вырезания/вставки или перетаскивания, а также позволяет вам чтобы прокомментировать последний элемент без возникновения синтаксической ошибки. Опускание конечной запятой является законным, но теряет преимущества обслуживания кода.

Я забыл, но Ник совершенно прав. Я тоже использовал конечную запятую с директивами компилятора. Без него условный код был бы намного более грязным и трудным для чтения.

Ответ 7

Это необязательно и полезно, если вы используете макрос, например

#ifdef _FLAG
    #define OPTS opt_four, opt_five,
#else
    #define OPTS // none
#endif
enum {
  opt_one,
  opt_two,
  opt_three,
  OPTS
};

Ответ 8

Нет, это не требуется и должно быть опущено для ясности кода. Его присутствие/отсутствие не имеет эффекта.

Ответ 9

Последняя запятая не требуется.

Я предпочитаю запятые по двум причинам:

  • Очистить git diffs.
  • Простое редактирование в редакторах с помощью линейных команд (например, Vim dd).

Ответ 10

Не требуется, чтобы некоторые компиляторы жаловались, если вы добавите их. например, Visual Studio 6.
Одно использование для запятой - это создание перечислений с использованием макросов c.

#define ELEMENT(x) x,

enum MyElements {
  ELEMENT(a)
  ELEMENT(b)
  ELEMENT(c)
};

Этот шаблон полезен, если у вас есть несколько вещей, которые вам нужно сделать с элементами, и вы хотите только их определить. Для более полного примера этого вы можете посмотреть код libiconv и утилиту iconv.

Ответ 11

Другие ответы упоминают об этом, но я хотел бы подчеркнуть, что конечная запятая не разрешена в стандартах C89 и С++, что делает ее проблемой переносимости со старыми или необычными компиляторами. Вот полезная ссылка, которая объясняет это и многие другие проблемы C/С++: http://david.tribble.com/text/cdiffs.htm#C99-enum-decl