C'est en fait un bien formée programme qui a deux tout aussi valables les chemins d'exécution, de sorte que les deux compilateurs sont à droite.
a[1] = a.size()
Dans cette expression, l'évaluation des deux opérandes de l' =
sont séquencé.
§1.9/15 [intro.exécution] Sauf indication contraire, l'évaluation des opérandes des opérateurs individuels et des sous-expressions des expressions individuelles sont séquencé.
Toutefois, les appels de fonction ne sont pas entrelacés, de sorte que les appels à l' operator[]
et size
sont en fait pour une période indéterminée séquencé, plutôt que de séquencé.
§1.9/15 [intro.exécution] Chaque évaluation dans la fonction appelante (y compris d'autres appels de fonction) qui n'est pas spécifiquement séquencée avant ou après l'exécution du corps de la fonction appelée est pour une période indéterminée séquencé à l'égard de l'exécution de la fonction appelée.
Cela signifie que les appels de fonction peut se produire dans l'une des deux commandes:
-
operator[]
alors size
-
size
alors operator[]
Si une clé n'existe pas et que vous appelez operator[]
avec cette clé, il sera ajouté à la carte, ce qui modifie la taille de la carte. Ainsi, dans le premier cas, la clé sera ajoutée, la taille sera récupéré (qui est 1), et 1
sera affecté à cette touche. Dans le second cas, la taille sera récupéré (qui est 0), la clé sera ajouté, 0
sera affecté à cette touche.
Remarque, ce n'est pas une situation qui amène à un comportement indéterminé. Comportement indéfini se produit lorsque deux modifications ou à une modification et une lecture de la même scalaire objet sont séquencé.
§1.9/15 [intro.exécution] Si un effet indésirable sur un scalaire objet est séquencé par rapport à un autre effet secondaire sur le même scalaire objet ou d'une valeur de calcul à l'aide de la valeur de la même scalaire objet, le comportement est indéfini.
Dans cette situation, ils ne sont pas non mais pour une période indéterminée séquencé.
Donc, ce que nous avons, c'est deux tout aussi valables les achats de l'exécution du programme. Soit qui pourrait arriver et les deux donnent valide de sortie. C'est indéterminée comportement.
§1.3.25 [defns.non spécifié]
un comportement non spécifié
comportement, pour un bien formée programme de construction et de rectification des données, qui dépend de la mise en œuvre
Donc, pour répondre à vos questions:
Le compilateur est de droite?
Deux d'entre eux sont.
Suis-je en train de faire quelque chose de mal?
Probablement. Il est peu probable que vous voulez écrire du code qui a deux chemins d'exécution de ce genre. Non spécifié comportement peut être bien, à la différence de comportement indéfini, car il peut être résolu en une seule observable de sortie, mais ce n'est pas la peine d'avoir, en premier lieu, si vous pouvez l'éviter. Au lieu de cela, ne pas écrire du code qui a ce genre d'ambiguïté. Selon ce que vous souhaitez exactement chemin d'accès correct, vous pouvez effectuer une des opérations suivantes:
auto size = a.size();
a[1] = size; // value is 0
Ou:
a[1];
a[1] = a.size(); // value is 1
Si vous voulez une 1
et vous savez que la clé n'existe pas encore, vous pouvez bien sûr faire le premier code, mais attribuer size + 1
.