¿Se requiere la última coma en C enum?

¿Se requiere la última coma en una statement de C enum?

es decir, ¿es la coma después de que se requiera VAL3 ?

 enum { Val1, Val2, Val3, } someEnum; 

¿Hay algún efecto secundario de dejarlo entrar / salir?

Gracias

No es obligatorio. La sección 6.7.2.2 de C99 enumera la syntax como:

 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 

Observe las dos primeras formas de enum-specifier , una con la coma final y otra sin ella.

Una de las ventajas que he visto al usarlo es en cosas como:

 enum { Val1, Val2, Val3, } someEnum; 

donde, si desea agregar (por ejemplo) Val4 y Val5 , solo copie y pegue la línea Val3 sin tener que preocuparse por ajustar las comas.

Y, como se señala en un comentario, también puede ser para simplificar los generadores de códigos automatizados para que no tengan que tener un manejo especial para el valor final. Pueden simplemente generar cada valor seguido de una coma.

Esto se puede comparar con el SQL visto a menudo:

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

En ese caso, where 1=1 está allí solo para que no tenga que poner un where antes de su primera cláusula y una antes de cada una subsecuente. Solo puede confiar en el hecho de que el where ya está allí y solo usarlo and para todos los que agregue.

Algunas personas pueden pensar que esto apesta a pereza y tienen razón, pero eso no es necesariamente algo malo 🙂

Cualquier optimizador de consultas DBMS decente debería ser capaz de eliminar una cláusula constante como esa antes de ir a las tablas de la base de datos.

Como todos los demás dicen, la coma no es obligatoria. Pero es nuevo en C99 (no estaba permitido en C89) y también se permitirá en la próxima versión de C ++.

Otra razón fundamental es hacer una diferencia entre un enumerador de “longitud” y un enumerador normal:

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

Ahora, puede poner en su directriz de encoding que el último elemento en su enumeración debe tener una coma aplicada, pero no si se trata de un elemento de “Longitud”, que simplemente indica cuántos elementos hay.

También ayuda a la generación automática de elementos (usando macros / preprocesadores) como explican otras respuestas.

En el estándar C89, la última coma no está permitida. Punto final.

Era una extensión común para permitirlo; en particular, fue respaldado por GCC, pero el estándar lo prohibió expresamente.

En el estándar C99, se permite la última coma, por simetría con los inicializadores de matriz y estructura, lo que siempre permitió la coma final en el último elemento.

6.7.2.2 Especificadores de enumeración

Sintaxis

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

La principal ventaja de permitir comas finales es que permite una generación más sencilla de la máquina de código (fuente C); no es necesario escribir un código de caso especial para el último elemento (o tal vez el primero) en la lista de inicializadores. Por lo tanto, progtwigs como Yacc y Lex, por nombrar solo dos, pueden ser un poco más simples.

No, no es obligatorio. El motivo es que facilita el uso del código de cortar y pegar, si no necesita preocuparse acerca de si la coma debe estar allí o no.

No, no es obligatorio; de hecho, diría que tenerlo es de mal estilo.

Como ya se dijo, no es obligatorio. La razón por la que se admite una coma final es que (suponiendo que los elementos se distribuyan uno en una línea) le permite reorganizar convenientemente el orden de los elementos en una enumeración usando cortar / pegar o arrastrar / soltar, y también le permite comentar el último elemento sin producir un error de syntax Omitir la coma final es legal, pero pierde estas ventajas de mantenimiento del código.

Lo había olvidado, pero Nick tiene toda la razón. Yo también he explotado la coma final con las directivas del comstackdor. Sin él, el código condicional habría sido mucho más complicado y difícil de leer.

Es opcional y útil, por ejemplo, si usa macro, por ejemplo

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

No, no es obligatorio y debe omitirse para la claridad del código. Su presencia / ausencia no tiene efecto.

La última coma final no es necesaria.

Prefiero las comillas finales por dos razones:

  1. Clean git diffs .
  2. Edición sencilla en editores con comandos basados ​​en línea (por ejemplo, dd de Vim).

No es necesario, de hecho, algunos comstackdores se quejan si agrega uno. por ejemplo, Visual Studio 6.
Un uso para la coma es crear enums usando c macros.

 #define ELEMENT(x) x, enum MyElements { ELEMENT(a) ELEMENT(b) ELEMENT(c) }; 

Este patrón es útil si hay varias cosas que debe hacer con los elementos y solo desea definirlos una vez. Para un ejemplo más completo de esto, puede ver el código de la utilidad libiconv y iconv.

Otras respuestas lo mencionan, pero me gustaría destacar que la coma final no está permitida en los estándares C89 y C ++, lo que lo convierte en un problema de portabilidad con comstackdores antiguos o poco comunes. Aquí hay un enlace útil que explica este y muchos otros problemas de C / C ++: http://david.tribble.com/text/cdiffs.htm#C99-enum-decl

El final , en una definición de enum o inicializador de matriz es opcional, pero bastante útil, especialmente en listas que abarcan múltiples líneas. Está permitido desde C99 por razones de simetría, ya que le da a todas las líneas la misma estructura para cada elemento:

 enum DAY { MON = 1, TUE, WED, THU, FRI, SAT, SUN, }; 

Hace que sea más fácil generar contenidos de matriz con scripts y evita situaciones propensas a errores en las que agregar elementos extra a una matriz, pero olvidarse de agregar una coma puede pasar desapercibido:

 const char *osnames[] = { "CP/M", "MS/DOS", "Windows" } 

Agregar elementos adicionales:

 const char *osnames[] = { "CP/M", "MS/DOS", "Windows" "Linux", "OS/X" }; 

Observe la coma que falta en el medio de la lista: el comstackdor analiza la tercera cadena como "WindowsLinux" y el error no genera un error de syntax.

Con el final , en cada línea, es mucho más fácil agregar y eliminar elementos sin modificar otras líneas. Es incluso más útil si las líneas se comstackn condicionalmente como en este ejemplo:

 const char *osnames[] = { "CP/M", "MS/DOS", "Windows", #ifdef __UNIX__ "Linux", "OS/X", #endif };