Is the last comma required in a C enum declaration?
That is, is the comma after Val3
required?
enum { Val1, Val2, Val3, } someEnum;
Are there any side-effects of leaving it in/out?
Is the last comma required in a C enum declaration?
That is, is the comma after Val3
required?
enum { Val1, Val2, Val3, } someEnum;
Are there any side-effects of leaving it in/out?
It's not required. Section 6.7.2.2
of C99 lists the syntax as:
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
Notice the first two forms of enum-specifier
, one with the trailing comma and one without.
One advantage I've seen to using it is in things like:
enum {
Val1,
Val2,
Val3,
} someEnum;
where, if you want to add in (for example) Val4
and Val5
, you just copy and paste the Val3
line without having to worry about adjusting commas.
It can also be to simplify automated code generators so that they don't have to have special handling for the final value. They can just output every value followed by a comma.
This can be likened to the oft-seen SQL:
select fld1, fld2 from tbl where 1=1 and fld1 > 8
In that case, the where 1=1
is there only so that you don't have to put a where
before your first clause and an and
before each subsequent one. You can just rely on the fact that the where
is already there and just use and
for all the ones you add.
Some people may think this reeks of laziness and they're right, but that's not necessarily a bad thing :-)
Any decent DBMS query optimiser should be able to strip out constant clause like that before going to the database tables.
Like everyone else says, the comma is not required. But it's new in C99 (wasn't allowed in C89) and will be allowed in the next version of C++ too.
One other rationale is to make a difference between a "length" enumerator and a normal enumerator:
enum Items {
A,
B,
C,
LENGTH
};
Now, you can put into your coding guideline that the last item in your enumeration should have a comma applied, but not if it is a "Length" item - which just tells how many items there are.
It also helps for automatic generation of items (using macros/preprocessors) like other answers explain.
In standard C89, the last comma is not permitted. Full stop.
It was a common extension to allow it; in particular, it was supported by GCC, but the standard expressly disallowed it.
In standard C99, the last comma is allowed, for symmetry with array and structure initializers, which always did allow the trailing comma on the last item.
6.7.2.2 Enumeration specifiers
Syntax
enum-specifier: enum identifieropt { enumerator-list } enum identifieropt { enumerator-list , } enum identifier
The primary advantage of permitting trailing commas is that it permits easier machine generation of (C source) code - you do not have to write special case code for the last (or, maybe, the first) item in the list of initializers. Hence, programs like Yacc and Lex, to name but two, can be slightly simpler.
The trailing ,
in an enum
definition or array initializer is optional, but quite useful, especially in lists spanning multiple lines. It is allowed since C99 for reasons of symmetry as it gives all lines the same structure for each item:
enum DAY {
MON = 1,
TUE,
WED,
THU,
FRI,
SAT,
SUN,
};
It makes it easier to generate array contents with scripts and avoids error prone situations where adding extra elements to an array but forgetting to add a comma might go unnoticed:
const char *osnames[] = {
"CP/M",
"MS/DOS",
"Windows"
}
Adding extra items:
const char *osnames[] = {
"CP/M",
"MS/DOS",
"Windows"
"Linux",
"OS/X"
};
Notice the missing comma in the middle of the list: the compiler parses the third string as "WindowsLinux"
and the bug does not generate a syntax error.
With the trailing ,
on each line, it is much easier to add and delete items without modifying other lines. It is even more useful if lines are compiled conditionally as in this example:
const char *osnames[] = {
"CP/M",
"MS/DOS",
"Windows",
#ifdef __UNIX__
"Linux",
"OS/X",
#endif
};
No it's not required. The reason being, it makes it easier for the purposes of cut and paste code, if you don't need to worry about whether the comma is meant to be there or not.
No it is not required - in fact I would say having it there is bad style.
As already stated it is not required. The reason that a trailing comma is supported is that it (assuming the items are laid out one to a line) it allows you to conveniently rearrange the order of items in an enumeration using cut/paste or drag/drop, and it also allows you to comment out the last item without producing a syntax error. Omitting the trailing comma is legal but loses these code maintenance advantages.
I'd forgotten but Nick is quite right. I too have exploited the trailing comma with compiler directives. Without it, the conditional code would have been a lot messier and harder to read.
It's optional and useful, if say you use macro, e.g.
#ifdef _FLAG
#define OPTS opt_four, opt_five,
#else
#define OPTS // none
#endif
enum {
opt_one,
opt_two,
opt_three,
OPTS
};
The last trailing comma is not required.
I prefer trailing commas for two reasons:
dd
).Other answers mention it but I'd just like to highlight that the trailing comma is disallowed in standards-conforming C89 and C++, which makes it a portability issue with old or uncommon compilers. Here's a useful link that explains this and many other C/C++ issues: http://david.tribble.com/text/cdiffs.htm#C99-enum-decl
No, it's not required and should be omitted for code clarity. Its presence/absence has no effect.
Its not required, infact some compilers complain if you add one. for instance Visual Studio 6.
One use for the comma is for creating enums using c macros.
#define ELEMENT(x) x,
enum MyElements {
ELEMENT(a)
ELEMENT(b)
ELEMENT(c)
};
This pattern is useful if you there are several things you need to do with the elements and only want to define them once. For a more complete example of this you can look at the code of the libiconv and the iconv utility.
#define ALL_ELEMENTS(ELEMENT) ELEMENT(a) ELEMENT(b) ELEMENT(c)
. You then #define ELEMENT
to whatever you need at any particular time, and then invoke the ALL_ELEMENTS
macro. –
Strahan © 2022 - 2024 — McMap. All rights reserved.