int a[] = {1,2,}; Why is a trailing comma in an initializer-list allowed?
Asked Answered
A

21

362

Maybe I am not from this planet, but it would seem to me that the following should be a syntax error:

int a[] = {1,2,}; //extra comma in the end

But it's not. I was surprised when this code compiled on Visual Studio, but I have learnt not to trust MSVC compiler as far as C++ rules are concerned, so I checked the standard and it is allowed by the standard as well. You can see 8.5.1 for the grammar rules if you don't believe me.

enter image description here

Why is this allowed? This may be a stupid useless question but I want you to understand why I am asking. If it were a sub-case of a general grammar rule, I would understand - they decided not to make the general grammar any more difficult just to disallow a redundant comma at the end of an initializer list. But no, the additional comma is explicitly allowed. For example, it isn't allowed to have a redundant comma in the end of a function-call argument list (when the function takes ...), which is normal.

So, again, is there any particular reason this redundant comma is explicitly allowed?

Adulation answered 12/8, 2011 at 16:36 Comment(20)
Note also that VIM's syntax indentation appears to push this style - I've found that indentation can be an issue if you don't use that extra comma.Putto
Every one seems to be agreeing to 'ease of adding new line' - but are people defining language specifications really bother about such things? If they are really that understanding then why don't they ignore a missing ; when it's clear next token is actually a next statement.Contrition
@YetAnotherUser: Yes, language designers consider such things. Allowing you to drop semicolons would have a much larger impact and would be highly ambiguous in many parts of the language (remember, whitespace is not semantic in C). An extra comma is this case is not ambiguous. An extra semicolon is almost never ambiguous, and so is allowed as well. In the case where it is ambiguous (after a for() for instance), adding it throws a compiler warning.Gaberones
Reverse your question, and you end up with: "Why should this be explicitly disallowed?" Do you have an answer for that?Gyrus
@Rob: +1, but a semicolon after a for() is not "ambiguous" at all.Gyrus
@Tomalak: It is ambiguous to a human reader, and is often a mistake. That is why it throws a warning. Similarly if (x = 1) is not ambiguous in the grammar, but it is very ambiguous to humans, and thus throws a warning.Gaberones
@Rob: How it is ambiguous? It's well-defined what for (a; b; c); means. There is no ambiguity here, neither for the compiler nor for the programmer. That it's often a mistake and easy to miss is pertinent.Gyrus
@Rob: Your if example is not ambiguous either. I don't think "ambiguous" means what you think it means!Gyrus
@Tomalak: You're right in that it's unambiguous, but 87% of the time, it's also not what the programmer wants.Mephitic
I've shot myself in the foot a couple times with this issue in javascript; IE (of course) doesn't like it and barfs when it finds one, but other browsers accept it.Santiago
@Alex: Indeed. But "ambiguous" is not the correct term.Gyrus
As long as we agree that it is something useful for the compiler to protect us from, while a trailing comma in an array declaration is not something useful for the compiler to protect us from.Gaberones
I find this feature indispensable, and it raises my ire to no end when I deal with languages that do forbid the trailing comma (SQL, I'm lookin' at you)Strap
What's most surprising in this subject, is how such trivialities evoke such disproportional interest and voting frenzy.Bremble
Definitely useful and often seen in enumWillamina
Several related questions: #2312364 , https://mcmap.net/q/93752/-trailing-commas-and-c , #793253 , https://mcmap.net/q/93754/-why-is-this-c-snippet-legal . The last one could be argued to be a dupe, although it's asking for C# instead of C++.Ira
@GeneBushuyev: en.wikipedia.org/wiki/Parkinson%27s_law_of_trivialityForensic
I wish it was allowed for template parameters, too!Obviate
What about when using the Yoda comma? int a[] = {,1,2}; stackoverflow.com/questions/10483635Cuss
I don't know how many of you use SQL, but it does not have this feature and commas there can feel absolutely antagonistic. I'm so happy to know the C and C++ developers took time to make this one little thing that much easier to use. (and so many others we often don't even think of) And this thread is great! Now I know indeed, this is NOT undefined in any way shape or form and I AM allowed to use it. And it was the question that answered me.Traitor
A
454

It makes it easier to generate source code, and also to write code which can be easily extended at a later date. Consider what's required to add an extra entry to:

int a[] = {
   1,
   2,
   3
};

... you have to add the comma to the existing line and add a new line. Compare that with the case where the three already has a comma after it, where you just have to add a line. Likewise if you want to remove a line you can do so without worrying about whether it's the last line or not, and you can reorder lines without fiddling about with commas. Basically it means there's a uniformity in how you treat the lines.

Now think about generating code. Something like (pseudo-code):

output("int a[] = {");
for (int i = 0; i < items.length; i++) {
    output("%s, ", items[i]);
}
output("};");

No need to worry about whether the current item you're writing out is the first or the last. Much simpler.

Anthe answered 12/8, 2011 at 16:39 Comment(19)
This is especially if you were using macros to add items to arrays. Using macros don't have the smarts to distinguish when not to add a comma, or rather adding such logic makes macros inherently more complex.Contort
Also, when using an VCS, the "diff" between two versions is cleaner since only one line changes when an item is added or removed.Temuco
If the justification is to make code generation simpler, then why not adopt the no parenthesis style of some funcional languages? and why not to infer all types? and remove the semicolons? and so on. I think the real reason was a very subjective and unfortunate criteria of the language designers.Nubble
@Néstor: Why "unfortunate"? What's the downside here? Just because some consideration has been given to code generation (and easy manipulation) for one tiny part of the language doesn't mean it has to be the primary motivation behind all decisions in the language. Type inference, removal of semi-colons etc have huge implications for the language. You're setting up a false dichotomy here, IMO.Anthe
Unfortunate because is inconsistent with other rules such as commas between method arguments, why the code-generation guys didn't get "helped" there? My reference to type inference, removal of semi-colons, etc. were to put an exaggerated example of a great help for code-generation. In other words, IMHO, or the language is fully consistent or is fully code-generation oriented.Nubble
@Néstor: That's where pragmatism wins over dogmatism: why does it have to be fully one thing or fully the other, when it's more useful to be a mixture of both? How does it actually get in the way, being able to add a comma at the end? Is this an inconsistency which has ever impeded you in any sense? If not, please weigh that irrelevant inelegance against the practical benefits of allowing a comma at the end.Anthe
its supported in a number of other languages besides c++ as well i know that php and c# support this so its not a c++ only thingPedro
I once stumbled across this issue when I wrote a script generating C code describing a 3D-Model and was happy that I didn't have to handle the last entry separately.Irishirishism
Generating code - can we say its done 10% or less times; rest of the time it involves typing in code. Statistically significant or not, those ferocious coders who blast off 100s of characters per minute, cannot afford to type in 2 more (or 20 more for that matter) characters? I'm not complaining, but this justification seems odd. I think it makes life easy on someone else's side, MS maybe?Strade
@Mrchief: It's not a matter of typing rate - it's a matter of simplicity, when copying, removing or reordering items. It made my life simpler just yesterday. With no downside, why not make life easier? As for trying to point the finger at MS, I strongly suspect this has been in C since before Microsoft even existed... You say this justification seems odd, but I bet it benefits thousands of developers across hundreds of companies every single day. Isn't that a better explanation than looking for something that benefits compiler writers?Anthe
Totally with you, my thought is, why not make life easier in other places too? As a sidenote and a bit ironically, another MS product totally despises the trailing comma. :)Strade
@Mrchief: I suspect it wouldn't be nearly as useful in other places - because most other places don't use a homogeneous list of items. For example, for method calls, reordering parameters is something which generally takes a lot more care due to the type system. The position makes a semantic difference, not just an order-of-appearance difference. (This doesn't hold as much water for named arguments, of course.) It feels like this was a single "let's put it in for this case for pragmatic reasons, but keep the language itself simpler elsewhere" decision.Anthe
Well, I was referring to other things, such as being able to say: public property int Index; (for auto-implemented properties primarily) which is much easier to type in (less chars, all in same row), more readable than ugly public int Index { get; set; }; and I guess tad easier for code generation as well.Strade
@Mrchief: Introducing new keywords after release is a tricky business. It's possible that this wouldn't cause any problems (like other contextual keywords), but I'm not entirely sure... and how would you make a public "getter" with a private "setter" that way? I wouldn't want to have two different syntaxes for it... (Personally I wish field-like events were declared as public event EventHandler Foo { add; remove; }; to make them clearer, but there we go...)Anthe
"another MS product totally despises the trailing comma" -- I think Mrchief was really talking about object and array literals in IE6, IE7, and IE8 too IIRC.Higgledypiggledy
@NéstorSánchezA. I posted an answer on this rationale, as expressed in "Deep C secrets"Cummine
I wonder if any languages use item-intiator or statement-initiator characters? If e.g. a language required each item of a list, including the first, to be preceded by a colon, then adding items to a list anywhere, whether at the beginning or end, would pose no problem, and in cases where an item or statement needed to span multiple lines, the lack of an item-initiator character on the next line might be more conspicuous than the lack of an item-terminator or item-separator at the end of the previous line.Autarchy
This reminds me of the Oxford Comma debate. In any case, especially for matrix definitions, I think allowing the comma is much better: each line has a well-defined index-independent syntax. This is coding, not English!Modify
@Strade the annotated C++ reference manual says this came from C and the C99 rationale which I quote in my answer below says provides flexibility in adding or deleting members from an initializer list, and simplifies machine generation of such lists.Meryl
E
132

It's useful if you do something like this:

int a[] = {
  1,
  2,
  3, //You can delete this line and it's still valid
};
Etz answered 12/8, 2011 at 16:39 Comment(9)
I'm surprised C++ has this, and many other languages don't (i.e Javascript)Sudorific
JavaScript supports this syntax: var a = [1, 2,];, so do most other languages I know... ActionScript, Python, PHP.Emendate
@Sean That'll cause a parse error in IE JavaScript, so beware!Etz
It doesn't for me in IE9. But it does do something strange... it creates a null element. I will beware.Emendate
@Sean Sorry, you're correct - it's not a parse error in IE, but it will insert an extra element set to undefined.Etz
C# also allows this in some cases.Incomplete
@Sean Fujiwara: Mathematica has the same issue.Comfortable
@Skilldrick: Well, technically it won't. Before ES5, the language didn't support trailing comma. However, the empty array element was undefined. Therefore, in JavaScript you can write [, 2]. Yes, it's completely pointless, but it works.Fulbert
Most frustratingly, JSON doesn't support this syntax.Stonemason
P
37

Ease of use for the developer, I would think.

int a[] = {
            1,
            2,
            2,
            2,
            2,
            2, /*line I could comment out easily without having to remove the previous comma*/
          }

Additionally, if for whatever reason you had a tool that generated code for you; the tool doesn't have to care about whether it's the last item in the initialize or not.

Polyvalent answered 12/8, 2011 at 16:40 Comment(0)
C
31

I've always assumed it makes it easier to append extra elements:

int a[] = {
            5,
            6,
          };

simply becomes:

int a[] = { 
            5,
            6,
            7,
          };

at a later date.

Clover answered 12/8, 2011 at 16:39 Comment(9)
I do not think making editing slightly faster is a good reason for messing up the syntax. IMHO this is just another weird C++ feature.Amsterdam
@Giorgio: Well, it's inherited from C. It's entirely possible that it's just an oversight in the original language specification, that happens to have a useful side-effect.Clover
Ok, I didn't know that it comes from C. I just checked that it is allowed in Java, too. It feels kind of weird though: in my intuition the comma is a separator not a terminator. Furthermore, it is possible to omit the last comma. So, is it a terminator, a separator, or both? But OK, this feature is available and it is good to know.Amsterdam
@Amsterdam - source code is for humans, not machines. Little things like this to keep us from making simple transposition errors are a blessing, not an oversight. For reference, it also works this way in PHP and ECMAScript (and therefore JavaScript and ActionScript), although it is invalid in JavaScript object notation (JSON) (e.g. [1,2,3,] is OK but {a:1, b:2, c:3,} is not).Dunedin
@Amsterdam - I'd say that rather than messing up the syntax, this improves the syntax. I can't count the number of times I've been glad you can do this.Presbyterate
It's also allowed in the latest C# specificationTypeset
@Groky: The more I think about it the more I am convinced that the syntax of a programming language should be as simple and consistent as possible and with as few exceptions as possible: this makes it easier to learn the language (fewer rules to remember). The advantage of saving one or two keystrokes when adding / removing an item to / from a list (which, by the way, I do not do that often compared to the total amount of time I spend coding) seems rather trivial to me compared to having a clearly defined syntax.Amsterdam
@Giorgio: And this is consistent: "foo = 1," wherever in the array that entry is.Presbyterate
@Amsterdam I posted an answer considering this, as found in the book "Deep C secrets"Cummine
M
28

I am surprised after all this time no one has quoted the Annotated C++ Reference Manual(ARM), it says the following about [dcl.init] with emphasis mine:

There are clearly too many notations for initializations, but each seems to serve a particular style of use well. The ={initializer_list,opt} notation was inherited from C and serves well for the initialization of data structures and arrays. [...]

although the grammar has evolved since ARM was written the origin remains.

and we can go to the C99 rationale to see why this was allowed in C and it says:

K&R allows a trailing comma in an initializer at the end of an initializer-list. The Standard has retained this syntax, since it provides flexibility in adding or deleting members from an initializer list, and simplifies machine generation of such lists.

Meryl answered 19/10, 2015 at 11:59 Comment(2)
Upvote for the most backed-up answer by literature, and the true source of this feature.Spanishamerican
Short and accurate. Such a pity people just missed this reply.Hebner
O
21

Everything everyone is saying about the ease of adding/removing/generating lines is correct, but the real place this syntax shines is when merging source files together. Imagine you've got this array:

int ints[] = {
    3,
    9
};

And assume you've checked this code into a repository.

Then your buddy edits it, adding to the end:

int ints[] = {
    3,
    9,
    12
};

And you simultaneously edit it, adding to the beginning:

int ints[] = {
    1,
    3,
    9
};

Semantically these sorts of operations (adding to the beginning, adding to the end) should be entirely merge safe and your versioning software (hopefully git) should be able to automerge. Sadly, this isn't the case because your version has no comma after the 9 and your buddy's does. Whereas, if the original version had the trailing 9, they would have automerged.

So, my rule of thumb is: use the trailing comma if the list spans multiple lines, don't use it if the list is on a single line.

Override answered 16/8, 2011 at 17:41 Comment(0)
B
15

Trailing comma I believe is allowed for backward compatibility reasons. There is a lot of existing code, primarily auto-generated, which puts a trailing comma. It makes it easier to write a loop without special condition at the end. e.g.

for_each(my_inits.begin(), my_inits.end(),
[](const std::string& value) { std::cout << value << ",\n"; });

There isn't really any advantage for the programmer.

P.S. Though it is easier to autogenerate the code this way, I actually always took care not to put the trailing comma, the efforts are minimal, readability is improved, and that's more important. You write code once, you read it many times.

Bremble answered 12/8, 2011 at 16:47 Comment(5)
I disagree completely; [It is my opinion that] it has found its way into many languages created long after C precisely because it is advantageous for the programmer to be able to shift around the contents of the array, comment out lines willy-nilly, and so on, without having to worry about silly transposition-induced syntax errors. Are we not already stressed enough?Dunedin
@Dunedin -- by the same logic, why shouldn't trailing (anything) be allowed, how about int a = b + c +; or if(a && b &&); it will be easier to just copy-and-paste anything at the end and easier to write code generators. This issue is both trivial, and subjective, in such cases it's always good to do what's best for the code reader.Bremble
@Gene Bushuyev: Exactly! I often have long expressions with + or &&, with the operator at the end of the line and, of course, I have to spend some extra time when I want to remove the last operand of the expression. I think this comma syntax is really odd!Amsterdam
@GeneBushuyev - I disagree on those. While allowing trailing commas in arrays and the like is a bug-removing feature and makes your life easier as a programmer, I would for the pure sake of readability take measures to remove trailing AND (&&) statements, plusses and other miscellaneous operators from conditional statements. It's just plain ugly, IMO.Hanway
Regarding the && operator, sometimes I do conditionals like if (true \n && b1 \n && b2) so that I can add and remove lines as I need to.Ardine
L
15

I see one use case that was not mentioned in other answers, our favorite Macros:

int a [] = {
#ifdef A
    1, //this can be last if B and C is undefined
#endif
#ifdef B
    2,
#endif
#ifdef C
    3,
#endif
};

Adding macros to handle last , would be big pain. With this small change in syntax this is trivial to manage. And this is more important than machine generated code because is usually lot of easier to do it in Turing complete langue than very limited preprocesor.

Lookeron answered 20/4, 2018 at 20:55 Comment(0)
P
13

One of the reasons this is allowed as far as I know is that it should be simple to automatically generate code; you don't need any special handling for the last element.

Patently answered 12/8, 2011 at 16:41 Comment(0)
N
12

It makes code generators that spit out arrays or enumerations easier.

Imagine:

std::cout << "enum Items {\n";
for(Items::iterator i(items.begin()), j(items.end); i != j; ++i)
    std::cout << *i << ",\n";
std::cout << "};\n";

I.e., no need to do special handling of the first or last item to avoid spitting the trailing comma.

If the code generator is written in Python, for example, it is easy to avoid spitting the trailing comma by using str.join() function:

print("enum Items {")
print(",\n".join(items))
print("}")
Nelsen answered 12/8, 2011 at 16:46 Comment(0)
H
6

The reason is trivial: ease of adding/removing lines.

Imagine the following code:

int a[] = {
   1,
   2,
   //3, // - not needed any more
};

Now, you can easily add/remove items to the list without having to add/remove the trailing comma sometimes.

In contrast to other answers, I don't really think that ease of generating the list is a valid reason: after all, it's trivial for the code to special-case the last (or first) line. Code-generators are written once and used many times.

Homeland answered 12/8, 2011 at 16:40 Comment(0)
D
6

It allows every line to follow the same form. Firstly this makes it easier to add new rows and have a version control system track the change meaningfully and it also allows you to analyze the code more easily. I can't think of a technical reason.

Doubling answered 12/8, 2011 at 16:40 Comment(0)
F
6

The only language where it's - in practice* - not allowed is Javascript, and it causes an innumerable amount of problems. For example if you copy & paste a line from the middle of the array, paste it at the end, and forgot to remove the comma then your site will be totally broken for your IE visitors.

*In theory it is allowed but Internet Explorer doesn't follow the standard and treats it as an error

Featherweight answered 12/8, 2011 at 18:37 Comment(6)
JavaScript's "arrays" (which are just objects with a magical length property) are rather unusual anyway: var x = [,,,] is legal (except in IE < 9, but the spec says it's legal)Scherzando
According to the ECMAScript specification, it's perfectly valid; in theory it should work in any browser that implements JavaScript according to the said specification, particularly the part of the specification found here.Dunedin
Unfortunately JavaScript is all about making apps for the public. So no, it's not perfectly valid when ~50% users would have problems using your app. And yes, if I could I'd ban IE < 9 -- just too much hours spend on just making good code working there...Keeler
@Dere: yes, I said as much in my answer =)Featherweight
@Dunedin microsoft invents its own specifications and commands that other abide at least that mentality is changing (thank god)Pedro
@Andreas Bonini: The problem you describe can be solved by running a syntax checker on your code before shipping.Amsterdam
R
6

It's easier for machines, i.e. parsing and generation of code. It's also easier for humans, i.e. modification, commenting-out, and visual-elegance via consistency.

Assuming C, would you write the following?

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    puts("Line 1");
    puts("Line 2");
    puts("Line 3");

    return EXIT_SUCCESS
}

No. Not only because the final statement is an error, but also because it's inconsistent. So why do the same to collections? Even in languages that allow you to omit last semicolons and commas, the community usually doesn't like it. The Perl community, for example, doesn't seem to like omitting semicolons, bar one-liners. They apply that to commas too.

Don't omit commas in multiline collections for the same reason you don't ommit semicolons for multiline blocks of code. I mean, you wouldn't do it even if the language allowed it, right? Right?

Roborant answered 12/8, 2011 at 23:17 Comment(1)
There are languages (e.g. Pascal) that allow that. I.e. you have to choose between ; as a terminator (C) or as a separator (Pascal). Same for ','. It would be ok for me if ',' is a terminator, but then {1, 2, 3} must be a syntax error.Amsterdam
F
6

This is allowed to protect from mistakes caused by moving elements around in a long list.

For example, let's assume we have a code looking like this.

#include <iostream>
#include <string>
#include <cstddef>
#define ARRAY_SIZE(array) (sizeof(array) / sizeof *(array))
int main() {
    std::string messages[] = {
        "Stack Overflow",
        "Super User",
        "Server Fault"
    };
    size_t i;
    for (i = 0; i < ARRAY_SIZE(messages); i++) {
        std::cout << messages[i] << std::endl;
    }
}

And it's great, as it shows the original trilogy of Stack Exchange sites.

Stack Overflow
Super User
Server Fault

But there is one problem with it. You see, the footer on this website shows Server Fault before Super User. Better fix that before anyone notices.

#include <iostream>
#include <string>
#include <cstddef>
#define ARRAY_SIZE(array) (sizeof(array) / sizeof *(array))
int main() {
    std::string messages[] = {
        "Stack Overflow",
        "Server Fault"
        "Super User",
    };
    size_t i;
    for (i = 0; i < ARRAY_SIZE(messages); i++) {
        std::cout << messages[i] << std::endl;
    }
}

After all, moving lines around couldn't be that hard, could it be?

Stack Overflow
Server FaultSuper User

I know, there is no website called "Server FaultSuper User", but our compiler claims it exists. Now, the issue is that C has a string concatenation feature, which allows you to write two double quoted strings and concatenate them using nothing (similar issue can also happen with integers, as - sign has multiple meanings).

Now what if the original array had an useless comma at end? Well, the lines would be moved around, but such bug wouldn't have happened. It's easy to miss something as small as a comma. If you remember to put a comma after every array element, such bug just cannot happen. You wouldn't want to waste four hours debugging something, until you would find the comma is the cause of your problems.

Fulbert answered 10/5, 2014 at 16:56 Comment(0)
C
4

Like many things, the trailing comma in an array initializer is one of the things C++ inherited from C (and will have to support for ever). A view totally different from those placed here is mentioned in the book "Deep C secrets".

Therein after an example with more than one "comma paradoxes" :

char *available_resources[] = {
"color monitor"           ,
"big disk"                ,
"Cray"                      /* whoa! no comma! */
"on-line drawing routines",
"mouse"                   ,
"keyboard"                ,
"power cables"            , /* and what's this extra comma? */
};

we read :

...that trailing comma after the final initializer is not a typo, but a blip in the syntax carried over from aboriginal C. Its presence or absence is allowed but has no significance. The justification claimed in the ANSI C rationale is that it makes automated generation of C easier. The claim would be more credible if trailing commas were permitted in every comma-sepa-rated list, such as in enum declarations, or multiple variable declarators in a single declaration. They are not.

... to me this makes more sense

Cummine answered 30/7, 2015 at 14:16 Comment(6)
The prohibition against the comma in the enum case is somewhat interesting, since that's the case where the missing comma would pose the least ambiguity. Given struct foo arr[] = {{1,2,3,4,5}, {3,4,5,6,7}, }; there are two sensible meanings the language could assign: create a two-element array, or create a three-element array where the last item has default values. If C had adopted the later interpretation, I could see forbidding enum foo {moe, larry, curly, }; on the principle that there should only be one way to write the statement (without the comma), but...Autarchy
...given that C is willing to ignore the comma in a case where it could reasonably have been (but wasn't) assigned a significant meaning (which would be a strong argument in favor of forbidding it there) it's curious that it isn't willing in a case where the comma couldn't have a meaning [even if one interpreted enum foo {moe,,larry,curly,}; as skipping a number between moe and larry, it wouldn't generally matter whether the trailing comma was processed or ignored. The only case where it could matter would be if the last item was the maximum value for its declared type, and that...Autarchy
...could be handled by simply saying that overflow which occurs following the last assigned enumeration value should be ignored.Autarchy
@Autarchy There are languages, like C#, where a priori design research goes as far as considering IDE features and integration when devoloping the language. C was not (and couldn't have been) one of these languages.Cummine
Even with languages like C#, changing design objectives have resulted in some pretty severe design inconsistencies. For example, the language refrained from supporting any form of return-type overloading for normal methods and operators (even though the underlying framework could support it) because it was seen as contrary to the goal of having a simple-to-compile language, but lambda evaluation includes type inference rules whose resolution is NP-complete. Adding new method/operator overloading rules might break existing code (though I think good rules could minimize such danger)...Autarchy
...but I don't see such issues in C's trailing-comma rules. IMHO, one of the major factors in deciding what to allow/forbid should be whether people who generally knew a language but not a particular feature would likely to incorrectly guess that feature's meaning. By that standard, int foo[] = {1,2,}; is much more dangerous than enum {LARRY, CURLY, };, and it is unlikely that the meaning of any existing code (including code allowed via compiler extensions) would change mening if the latter were made legitimate.Autarchy
J
2

In addition to code generation and editing ease, if you want to implement a parser, this type of grammar is simpler and easier to implement. C# follows this rule in several places that there's a list of comma-separated items, like items in an enum definition.

Jimjams answered 16/8, 2011 at 21:3 Comment(0)
S
1

It makes generating code easier as you only need to add one line and don't need to treat adding the last entry as if it's a special case. This is especially true when using macros to generate code. There's a push to try to eliminate the need for macros from the language, but a lot of the language did evolve hand in hand with macros being available. The extra comma allows macros such as the following to be defined and used:

#define LIST_BEGIN int a[] = {
#define LIST_ENTRY(x) x,
#define LIST_END };

Usage:

LIST_BEGIN
   LIST_ENTRY(1)
   LIST_ENTRY(2)
LIST_END

That's a very simplified example, but often this pattern is used by macros for defining things such as dispatch, message, event or translation maps and tables. If a comma wasn't allowed at the end, we'd need a special:

#define LIST_LAST_ENTRY(x) x

and that would be very awkward to use.

Stationmaster answered 23/4, 2018 at 12:15 Comment(0)
O
0

So that when two people add a new item in a list on separate branches, Git can properly merge the changes, because Git works on a line basis.

Organza answered 25/12, 2019 at 17:48 Comment(0)
S
0

It makes editing the code a lot easier. I'm comparing editinc c/c++ array elements with editing json documents - if you forget to remove the last comma, the JSON will not parse. (Yes, I know JSON is not meant to be edited manually)

Sanderlin answered 16/1, 2023 at 20:43 Comment(0)
E
-4

If you use an array without specified length,VC++6.0 can automaticly identify its length,so if you use "int a[]={1,2,};"the length of a is 3,but the last one hasn't been initialized,you can use "cout<

Erdman answered 18/8, 2011 at 1:10 Comment(1)
Is this a bug for VC6 which is not conformant with the standard?Putrefaction

© 2022 - 2024 — McMap. All rights reserved.