Ce qui a fait i = ++ i + 1; juridique en C++17?

Avant de commencer à hurler comportement indéfini, c'est explicitement répertoriés dans N4659 (C++17)

  i = i++ + 1;        //the value of i is incremented

Encore dans N3337 (C++11)

  i = i++ + 1;        //the behavior is undefined

Ce qui a changé?

De ce que j'ai pu rassembler, à partir de [N4659 de base.exec]

Sauf indication contraire, l'évaluation des opérandes des opérateurs individuels et des sous-expressions des expressions individuelles sont séquencé. [...] La valeur des calculs des opérandes d'un opérateur sont séquencée avant de la valeur de calcul du résultat de l'opérateur. Si un effet indésirable sur un emplacement de la mémoire est séquencé par rapport à un autre effet secondaire sur le même emplacement de mémoire ou une valeur de calcul à l'aide de la valeur de tout objet dans le même emplacement de mémoire, et ils ne sont pas potentiellement concurrentes, le comportement est indéfini.

valeur est défini à [N4659 de base.type]

Pour trivialement copiable types, la valeur de la représentation est un ensemble de bits dans la représentation des objets qui détermine un valeur, qui est un élément discret de la mise en œuvre-ensemble défini de valeurs

De [N3337 de base.exec]

Sauf indication contraire, l'évaluation des opérandes des opérateurs individuels et des sous-expressions des expressions individuelles sont séquencé. [...] La valeur des calculs des opérandes d'un opérateur sont séquencée avant de la valeur de calcul du résultat de l'opérateur. 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.

De même, la valeur est définie à [N3337 de base.type]

Pour trivialement copiable types, la valeur de la représentation est un ensemble de bits dans la représentation des objets qui détermine un valeur, qui est un élément discret de la mise en œuvre-ensemble défini de valeurs.

Ils sont identiques à l'exception de la mention de la simultanéité qui n'a pas d'importance, et avec l'utilisation de emplacement de mémoire au lieu de scalaire objet, où

Arithmétique types, l'énumération des types, des types pointeur, pointeur de types de membres, std::nullptr_t, et de cv qualifiés versions de ces types sont appelés collectivement les types scalaires.

Qui n'affecte pas l'exemple.

De [N4659 expr.cul]

De l'opérateur d'affectation (=) et le composé des opérateurs d'affectation à un groupe de droite à gauche. Tous exigent une modifiables lvalue comme leur opérande de gauche et de retourner une lvalue se référant à l'opérande de gauche. Le résultat en tout cas est un peu de champ si l'opérande de gauche est un peu de champ. Dans tous les cas, la cession est séquencé après la valeur de calcul de la droite et de la gauche opérandes, et avant que la valeur de calcul de l'expression d'affectation. L'opérande de droite est séquencée avant de l'opérande de gauche.

De [N3337 expr.cul]

De l'opérateur d'affectation (=) et le composé des opérateurs d'affectation à un groupe de droite à gauche. Tous exigent une modifiables lvalue comme leur opérande de gauche et de retourner une lvalue se référant à l'opérande de gauche. Le résultat en tout cas est un peu de champ si l'opérande de gauche est un peu de champ. Dans tous les cas, la cession est séquencé après la valeur de calcul de la droite et de la gauche opérandes, et avant que la valeur de calcul de l'expression d'affectation.

La seule différence étant la dernière phrase d'être absent dans N3337.

La dernière phrase, cependant, ne devrait pas avoir d'importance que l'opérande de gauche i est ni "un autre effet secondaire" ni "à l'aide de la valeur de la même scalaire objet" comme le id-expression est une lvalue.

  • Vous avez identifié la raison: En C++17, l'opérande de droite est séquencée avant de l'opérande de gauche. En C++11 il n'y avait pas de séquençage. Ce qui, précisément, est à votre question?
  • Voir la dernière phrase.
  • Il y a deux séquencé effets secondaires, écrit: i = a pour effet de bord de la rédaction de i. i++ a pour effet de bord de la rédaction de i.
  • Si elles sont non, que ferait l'exemple dans la norme donc absolument mauvais que je serais très hésitant à se prétendent qu'ils sont séquencé.
  • Ils sont non en C++11, séquencé en C++17. D'où les différents exemples.
  • Quelqu'un aurait-il un lien pour la motivation de ce changement? Je voudrais un analyseur statique pour être en mesure de dire "vous ne voulez pas faire que" lorsqu'un code comme i = i++ + 1;.
  • c'est à partir de l'étude p0145r3.pdf: "Affiner l'Évaluation de l'Expression de l'Ordre pour Idiomatiques C++".
  • Qui peu de ce que, exactement - je ne vois rien de pertinent, mais peut-être que c'est mon mauvais.
  • Sur un rapide coup d'œil de ce document, l'article 5 implique qu'il ne couvre pas le cas de ++.
  • numéro de l'article 2 dit que c'est contre-intuitif et même les experts ne parviennent pas à faire la bonne chose dans tous les cas. C'est à peu près tout de leur motivation.
  • le document ajoute que le libellé de l'opérateur d'affectation. Il ne fonctionne pas sur unaire expressions dans tous les contextes, mais affectent la façon dont elles sont traitées dans le cadre de l'affectation que l'on a accepté la réponse explique.
  • Je dirais qu'un compilateur qui ne peut pas lire que c'est buggé.
  • N4700 est un plus projet de C++17.
  • Donc, ce qui se passe quand vous allez "c=c++ +1;"? Est-ce la même chose que "c=c+2"?
  • que serait c=c+1, depuis tha valeur produite par le c++ + 1 c+1.
  • L'OP de la première ligne de code mentionne ce qui n'. Bien qu'à mon humble avis, le commentaire doit avoir dit "obtient 1, ajouté à cela" plutôt que "est incrémenté".
  • Ces Questions sont les raisons de cette proposition existe: open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0431r0.htm mais bien sûr, il n'était pas défendu correctement à toutes les réunions du comité et probablement juste de mourir d'une mort lente.

InformationsquelleAutor Passer By | 2017-12-07