351 votes

int a[] = {1,2,} ; Pourquoi une virgule de fin est-elle autorisée dans une liste d'initialisation ?

Je ne suis peut-être pas de cette planète, mais il me semble que ce qui suit devrait être une erreur de syntaxe :

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

Mais ce n'est pas le cas. J'ai été surpris par la compilation de ce code sur Visual Studio, mais j'ai appris à ne pas faire confiance au compilateur MSVC en ce qui concerne les règles du C++. est également autorisé par la norme. Si vous ne me croyez pas, vous pouvez consulter le point 8.5.1 pour les règles de grammaire.

enter image description here

Pourquoi cela est-il autorisé ? Il s'agit peut-être d'une question stupide et inutile, mais je veux que vous compreniez pourquoi je vous la pose. S'il s'agissait d'un sous-cas d'une règle de grammaire générale, je comprendrais - ils ont décidé de ne pas rendre la grammaire générale plus difficile juste pour interdire une virgule redondante à la fin d'une liste d'initialisateurs. Mais non, la virgule supplémentaire est explicitement autorisé. Par exemple, il n'est pas permis d'avoir une virgule redondante à la fin d'une liste d'arguments d'un appel de fonction (lorsque la fonction prend ... ), ce qui est normal .

Alors, encore une fois, y a-t-il une raison particulière pour laquelle cette virgule redondante est explicitement autorisé ?

0 votes

Notez également que l'indentation de la syntaxe du VIM semble favoriser ce style - j'ai constaté que l'indentation peut être un problème si vous n'utilisez pas la virgule supplémentaire.

12 votes

Tout le monde semble être d'accord sur la "facilité d'ajouter une nouvelle ligne" - mais est-ce que les les personnes définir les spécifications linguistiques se préoccupe vraiment de ces choses ? S'ils sont vraiment si compréhensifs, pourquoi n'ignorent-ils pas qu'il manque un ; lorsqu'il est clair que le prochain jeton est en fait une déclaration suivante.

36 votes

@YetAnotherUser : Oui, les concepteurs de langage prennent en compte ce genre de choses. Permettre de supprimer les points-virgules aurait un impact beaucoup plus important et serait très ambigu dans de nombreuses parties du langage (n'oubliez pas que les espaces blancs ne sont pas sémantiques en C). Dans ce cas, une virgule supplémentaire n'est pas ambiguë. Un point-virgule supplémentaire n'est presque jamais ambigu et est donc également autorisé. Dans le cas où il est ambigu (après un for() par exemple), son ajout provoque un avertissement du compilateur.

447voto

Jon Skeet Points 692016

Il facilite la génération du code source et l'écriture d'un code qui peut être facilement étendu ultérieurement. Réfléchissez à ce qu'il faut faire pour ajouter une entrée supplémentaire à.. :

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

... il faut ajouter la virgule à la ligne existante et ajouter une nouvelle ligne. Comparez cela avec le cas où les trois déjà est suivi d'une virgule, où il suffit d'ajouter une ligne. De même, si vous souhaitez supprimer une ligne, vous pouvez le faire sans vous soucier de savoir s'il s'agit de la dernière ligne ou non, et vous pouvez réorganiser les lignes sans vous préoccuper des virgules. En gros, cela signifie qu'il y a une uniformité dans la façon dont vous traitez les lignes.

Pensez maintenant à générer du code. Quelque chose comme (pseudo-code) :

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

Il n'est pas nécessaire de se demander si l'élément que vous écrivez est le premier ou le dernier. C'est beaucoup plus simple.

1 votes

C'est notamment le cas si vous utilisez des macros pour ajouter des éléments à des tableaux. L'utilisation de macros n'a pas l'intelligence de distinguer quand il ne faut pas ajouter une virgule, ou plutôt l'ajout d'une telle logique rend les macros intrinsèquement plus complexes.

95 votes

De plus, lorsqu'on utilise un VCS, la "différence" entre deux versions est plus nette puisqu'une seule ligne change lorsqu'un élément est ajouté ou supprimé.

4 votes

Si la justification est de rendre la génération de code plus simple, alors pourquoi ne pas adopter le style sans parenthèses de certains langages fonctionnels ? et pourquoi ne pas déduire tous les types ? et supprimer les points-virgules ? et ainsi de suite. Je pense que la véritable raison est un critère très subjectif et malheureux des concepteurs du langage.

128voto

Skilldrick Points 33002

C'est utile si vous faites quelque chose comme ça :

int a[] = {
  1,
  2,
  3, //You can delete this line and it's still valid
};

0 votes

Je suis surpris que le C++ ait cela, et que beaucoup d'autres langages ne l'aient pas (par exemple Javascript).

7 votes

JavaScript prend en charge cette syntaxe : var a = [1, 2,]; Il en va de même pour la plupart des autres langages que je connais... ActionScript, Python, PHP.

14 votes

@Sean Cela provoquera une erreur d'analyse dans IE JavaScript, donc attention !

37voto

vcsjones Points 51910

La facilité d'utilisation pour le développeur, je pense.

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

En outre, si, pour une raison quelconque, vous avez un outil qui génère du code pour vous, l'outil n'a pas à se préoccuper de savoir si c'est le dernier élément de l'initialisation ou non.

31voto

Oli Charlesworth Points 148744

J'ai toujours pensé que cela facilitait l'ajout d'éléments supplémentaires :

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

devient simplement :

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

à une date ultérieure.

3 votes

Je ne pense pas que le fait de rendre l'édition un peu plus rapide soit une bonne raison de bouleverser la syntaxe. Selon moi, il s'agit simplement d'une autre caractéristique bizarre du C++.

3 votes

@Giorgio : Eh bien, c'est hérité du C. Il est tout à fait possible qu'il s'agisse simplement d'un oubli dans la spécification originale du langage, qui s'avère avoir un effet secondaire utile.

0 votes

Ok, je ne savais pas que cela venait du C. Je viens de vérifier que c'est autorisé en Java aussi. C'est un peu bizarre quand même : dans mon intuition, la virgule est un séparateur et non un terminateur. De plus, il est possible d'omettre la dernière virgule. Alors, s'agit-il d'un terminateur, d'un séparateur ou des deux ? Mais bon, cette fonctionnalité est disponible et il est bon de le savoir.

15voto

Gene Bushuyev Points 3819

La virgule de fin est autorisée, je crois, pour des raisons de compatibilité ascendante. Il y a beaucoup de code existant, principalement généré automatiquement, qui met une virgule de fin. Cela facilite l'écriture d'une boucle sans condition particulière à la fin. Par exemple

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

Il n'y a pas vraiment d'avantage pour le programmeur.

P.S. Bien qu'il soit plus facile d'autogénérer le code de cette manière, j'ai toujours pris soin de ne pas mettre la virgule de fin, les efforts sont minimes, la lisibilité est améliorée, et c'est le plus important. Vous écrivez du code une fois, vous le lisez plusieurs fois.

7 votes

Je ne suis pas du tout d'accord ; [je suis d'avis qu'] elle a trouvé sa place dans de nombreux langages créés bien après le C précisément parce qu'il est avantageux pour le programmeur de pouvoir déplacer le contenu du tableau, commenter des lignes bon gré mal gré, et ainsi de suite, sans avoir à se soucier de stupides erreurs de syntaxe induites par la transposition. Ne sommes-nous pas déjà suffisamment stressés ?

12 votes

@Dereleased -- dans la même logique, pourquoi ne pas autoriser la terminaison (n'importe quoi), pourquoi pas int a = b + c +; o if(a && b &&); il sera plus facile de copier-coller n'importe quoi à la fin et plus facile d'écrire des générateurs de code. Cette question est à la fois triviale et subjective. Dans ce cas, il est toujours préférable de faire ce qui est le mieux pour le lecteur de code.

1 votes

@Gene Bushuyev : Exactement ! J'ai souvent de longues expressions avec + ou &&, avec l'opérateur à la fin de la ligne et, bien sûr, je dois passer un peu plus de temps lorsque je veux supprimer le dernier opérande de l'expression. Je pense que cette syntaxe de la virgule est vraiment étrange !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X