Est-ce que i, j = 1 est vraiment trompeur? [fermé]

11

Il existe un argument commun à propos de l'initialisation de plusieurs variables dans une seule ligne, c'est-à-dire:

Considérons par exemple int i, j = 1; ce qui pourrait amener certaines personnes à croire à tort que les deux variables sont initialisées

Nous pourrions affirmer que quelqu'un devrait connaître suffisamment la syntaxe de son langage pour ne pas s'y tromper. Un autre argument pourrait être que les développeurs apprennent tellement de langues que nous pouvons faire des erreurs entre les spécificités entre les langues.

Cependant, pour ce cas très spécifique, je me demande ce qui suit: existe-t-il même un langage où la syntaxe même i, j = 1 initialise les deux variables?

Sinon, cet argument ne s'applique pas.

Walfrat
la source
2
Si votre langage est sain d'esprit, la confusion potentielle est inoffensive car l'accès à une variable non initialisée déclenche une erreur de compilation.
CodesInChaos
4
@CodesInChaos dites-vous que C n'est pas sain d'esprit?
Baldrickk
2
Ce n'est pas parce qu'une langue permet quelque chose que vous ne causez pas de douleur inutile aux humains. Le seul endroit où ce code est demandé est pendant les questionnaires conçus pour punir ceux qui n'ont pas mémorisé la spécification de langue. J'ai toujours échoué à ce type de questions. Bleh.
candied_orange
2
Dans Visual Basic 6 Dim Apple, Orange, Pear as Fruitest une déclaration légale. Supposons que vous ne connaissiez pas VB. Votre première impression Appleest-elle de type Fruit? Ce n'est pas. N'oubliez pas que les langues sont souvent lues par des personnes qui ne sont pas des experts dans cette langue; si vous êtes un expert, utilisez le langage à bon escient pour communiquer clairement vos intentions même aux non-experts. Je n'utilise jamais plusieurs initialisations dans n'importe quelle langue.
Eric Lippert
13
De même: considérer var x = 1, y = 1.5; Est-ce la même chose que int x = 1; double y = 1.5;ou est-ce la même chose que double x = 1, y = 1.5;? Lorsque nous avons ajouté varC # 3.0, j'ai fait un sondage et j'ai découvert qu'environ la moitié des gens pensaient que le premier était "évidemment" correct et que l'autre moitié pensait que l'autre était "évidemment" correct, et nous l'avons donc rendu illégal. Une caractéristique qui induit en erreur la moitié de la population est une mauvaise caractéristique.
Eric Lippert

Réponses:

37

Je ne pense pas, mais ce n'est pas le but. Le fait est qu'il i, j = 0est très facilement confondu avec i = j = 0, ce qui initialise les deux. La clarté est l'exigence la plus importante sur le code source à côté de l'exactitude, et le fait que cette question se pose même prouve que la clarté n'est pas optimale.

Kilian Foth
la source
3
Je dirais également que si une telle déclaration n'initialise pas les deux déclarations, pourquoi existe-t-elle même?
Berin Loritsch
2
@BerinLoritsch dépend de la langue. Cela est souvent fait en JavaScript en raison du levage de déclaration: il est considéré par beaucoup comme la meilleure pratique de déclarer des variables en haut de l'étendue dans laquelle elles sont disponibles même si vous ne les initialisez pas jusqu'à l'endroit où elles sont utilisées dans le code . Presque tous les outils de transformation de code sortent de cette façon.
Jared Smith
1
Je suppose que c'est une chose si un outil de sortie de code fait cela, car cela est censé être approuvé. Cependant, pour les humains, je déconseille de combiner la déclaration et l'initialisation du dernier élément sur une seule ligne. Il ressemble juste à un bug qui attend de se produire.
Berin Loritsch
2
@JaredSmith Outre Maple, je ne peux pas penser à un langage où cela est actuellement souhaité, même C préfère maintenant plus proche de la portée (comme C ++ et la plupart des autres langages avec des compilateurs statiques à moitié décents) car il donne l'avantage d'arrêter les bogues potentiels et permet le compilateur pour décider quoi faire avec la variable tant que la fonctionnalité ne change pas, permettant potentiellement de meilleures optimisations étant donné que vous pourriez vous en tirer avec moins de registres.
2018
6
Quelle que soit la langue, on devrait se demander "Quel est l’ avantage d’écrire int i, j=1par rapport à int i; int j = 1(ou mieux encore, des lignes séparées)?"
chepner
2

Je pense que vous pouvez plaider pour chaque côté:

  • Kontra i, j = 0: Les
    mathématiciens utilisent cela pour signifier que les deux iet jsont censés être nuls.

  • Pro i, j = 0:
    C'est une simple question de connaître la priorité de vos opérateurs. Et si vous doutez de leur priorité, il est maintenant temps de la rechercher.

    C'est la même raison pour laquelle nous écrivons des trucs comme a.b += c[i]*d[i];sans les parenthèses. Bien sûr, cela équivaut à (a.b) += ((c[i])*(d[i]));, mais on peut s'attendre à ce que les programmeurs connaissent par cœur la priorité des opérateurs les plus utilisés et puissent rechercher la priorité des opérateurs lorsqu'ils ne sont pas sûrs. Ainsi, les parenthèses sont généralement considérées comme un encombrement inutile à moins qu'elles ne forcent un ordre d'évaluation différent de celui que la priorité de l'opérateur prescrirait.

    Bien sûr, il y a des exceptions. La priorité de <<et +est généralement considérée comme suffisamment ambiguë pour garantir des parenthèses dans les deux cas. Mais c'est l'exception qui confirme la règle.

Pour ma part, je tomberais plus du côté Pro, mais je suis prêt à m'en tenir à tout guide de style qui interdit de telles déclarations. Ce n'est pas une question qui mérite d'être combattue.

cmaster - réintégrer monica
la source
7
Je note qu'il int i, j = 0;n'y a aucun opérateur dedans. La seule expression dans cette instruction est 0et donc la priorité des opérateurs n'y entre pas. L'analyseur syntaxique ne traite pas ,comme l'opérateur de virgule ou =comme l'opérateur d'affectation; ce sont plutôt des parties grammaticales de la déclaration.
Eric Lippert
@EricLippert En ce qui concerne les règles de priorité, cette différence n'est pas pertinente: tout langage de style C que je connais utilise les mêmes priorités dans une déclaration que dans d'autres expressions. Tout le reste inviterait un désastre.
cmaster - réintègre monica
but programmers can be expected to know the precedence of the most used operators by heart, vous dites. Dans l'exemple que vous donnez, je ne suis pas sûr que la plupart des programmeurs (moyens) conçoivent l'opérateur d'accès aux membres ou l'opérateur d'index de tableau comme étant des opérateurs au sens mathématique, mais les considèrent plutôt comme des noms en langage naturel et la multiplication opérateur comme verbe. C'est pourquoi int i, j, k = 0;est une construction si diabolique, car elle se présente comme l'analogue du langage naturel des "variables int i, j et k, sont déclarées et doivent être mises à 0"!
Steve
@Steve La façon dont vous vous souvenez des règles de priorité en tant que programmeur dépend entièrement de vous. Si cela vous aide à les considérer comme des noms de la langue, faites-le. Cependant, dans ce cas, vous rencontrerez des problèmes lorsque vous verrez des choses comme *a[i], je ne pense pas que vous puissiez suffisamment analyser cela avec l'analogie des "noms". Quant à cela int i, j, k = 0;, cela pourrait signifier n'importe quoi si vous ne recherchez pas les règles: une troisième interprétation serait de déclarer int i, puis d'évaluer jet enfin d'assigner k = 0. À moins que vous ne connaissiez la syntaxe de votre langage, vous ne pouvez pas analyser de telles constructions. C'est votre problème si vous le faites de toute façon.
cmaster - réintègre monica
@cmaster, je n'exprimais pas ma stratégie de mémorisation spécifique haha. Je ne suis pas un programmeur C, donc ma connaissance de la priorité des opérateurs en C est de second ordre. Mais ce que j'ai remarqué quand j'ai regardé votre exemple, c'est que je ne pensais même pas à l'opérateur de multiplication comme ayant une priorité relative à l'opérateur d'index du tableau. Autrement dit, je n'ai pas lu en a[i]tant qu'opérateur d'index appliqué a, mais plutôt lu ensemble comme un élément syntaxique irréductible spécifiant l'opérande de l'opérateur de multiplication, et donc je n'ai même pas été invité à évaluer la priorité. (1/2)
Steve