9

Silly question, but why does the following line compile?

int[] i = new int[] {1,};

As you can see, I haven't entered in the second element and left a comma there. Still compiles even though you would expect it not to.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Razor
  • 17,271
  • 25
  • 91
  • 138
  • 4
    http://stackoverflow.com/questions/2311864/history-of-trailing-comma-in-programming-language-grammars – Josh Lee Mar 02 '10 at 06:31
  • I'm amazed anyone would be satisfied with the answer "Because that's what the spec says". Steck's and Jimmy's answers explain *why it is beneficial*. – Daniel Earwicker Mar 02 '10 at 07:16
  • I voted it up because I was impressed by the arrow.... – Jimmy Mar 02 '10 at 07:20
  • Oh yes, the arrow is fantastic. No one is complaining about the arrow. – Daniel Earwicker Mar 02 '10 at 07:27
  • @Earwicker: The question is not "How can I use this trailing comma?", but "Why does it compile"? From question to answer... – Luca Mar 08 '10 at 17:59
  • @Luca - by that reasoning we could have another 1000 questions about each feature of the language, asking "Why does this compile?", each with an answer from you saying "Because the standard says this..." Such an answer says almost nothing. The question contains a big clue: "Still compiles even though you would expect it not to." Actually you should expect it to compile, and a language that didn't compile it would be poorer. It's a feature, not a bug. The good answers explain this. – Daniel Earwicker Mar 08 '10 at 19:20

6 Answers6

11

I suppose because the ECMA 334 standard say:

array-initializer:
    { variable-initializer-list(opt) }
    { variable-initializer-list , }
variable-initializer-list:
    variable-initializer
    variable-initializer-list , variable-initializer
variable-initializer:
    expression
    array-initializer

As you can see, the trailing comma is allowed:

{ variable-initializer-list , }
                            ↑

P.S. for a good answer (even if this fact was already pointed by many users). :)

Trailing comma could be used to ease the implementation of automatic code generators (generators can avoid to test for last element in initializer, since it should be written without the trailing comma) and conditional array initialization with preprocessor directives.

Luca
  • 11,646
  • 11
  • 70
  • 125
10

This is syntax sugar. In particular, such record can be useful in code generation.

int[] i = new int[] {
    1,
    2,
    3,
};

Also, when you are writing like this, to add new line you need to add text only in single line.

Steck
  • 1,171
  • 9
  • 19
  • 1
    Annoying that this is allowed in arrays, but not in Enums, where they would be much more useful. – Jon Limjap Mar 02 '10 at 06:38
  • IMO, this and Jimmy's answer should be edited together and then the result accepted! And I would add the observation that this is how `;` works between statements, for exactly the same reason. And that in Erlang, where the trailing symbol is different (a dot instead of a comma), it may appear comfortingly similar to English at first but users end up hating it for the same reasons given here. – Daniel Earwicker Mar 02 '10 at 07:24
7

It should compile by definition.

There is no second element. A trailing comma is valid syntax when defining a collection of items.

i is an array of int containing a single element, i[0] containing the value 1.

Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
7

Another benefit of allowing a trailing comma is in combination with preprocessor directives:

int[] i = new[] {
#if INCLUDE1
   1,
#endif

#if INCLUDE2
   2,
#endif

#if INCLUDE3
   3,
#endif
};

Without allowing a trailing comma, that would be much more difficult to write.

R Samuel Klatchko
  • 74,869
  • 16
  • 134
  • 187
5

its so you can do this and copy/paste lines around without worrying about deleting/adding the commas in the correct places.

int[] i = new[] { 
   someValue(),
   someOtherValue(),
   someOtherOtherValue(),

   // copy-pasted zomg! the commas don't hurt!
   someValue(),
   someOtherValue(),
   someOtherOtherValue(),

};
Jimmy
  • 89,068
  • 17
  • 119
  • 137
3

Same goes for enums:

enum Foo
{
  Bar,
  Baz,
};
leppie
  • 115,091
  • 17
  • 196
  • 297