52 votes

Dans f (x), peut-on évaluer x avant f?

J'ai un programme C ++. Ce programme fait quelque chose comme ça:

 struct MyT {void memfunc(std::unique_ptr<MyT> arg);};
std::unique_ptr<MyT> obj = /* some init */;
obj->memfunc(std::move(obj));
 

Est-ce que cette garantie est valide ou puis-je appeler une fonction membre sur nullptr ?
Citations standard applicables.
Je sais que l'ordre d'évaluation des arguments n'est pas séquencé, mais je ne me souviens pas de la séquence utilisée pour appeler l'objet fonction.

19voto

Deduplicator Points 9096

Voici la citation qui prouve que toute évaluation nécessaire d'appeler une fonction et les effets indésirables liés à la séquence avant l'appel de fonction.
Aussi, toutes les autres évaluations sont pas spécifiquement séquencés sont pour une période indéterminée séquencé.
À ne pas imposer de toute commande de contraintes sur les sous-expressions évalué si les uns par rapport aux autres, ils restent non à l'égard les uns des autres.

1.9 l'exécution du Programme § 15

Sauf indication contraire, les évaluations 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 à soit anotherside effet 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.
Lors de l'appel d'une fonction (que ce soit ou non la fonction inline), chaque valeur de calcul et des effets secondaires associés avec n'importe quel argument de l'expression, ou avec le suffixe expression désignant la fonction appelée, est séquencée avant l'exécution de chaque instruction ou de l'expression dans le corps de la fonction appelée.
[ Note: la Valeur des calculs et des effets secondaires associés avec différentes expressions d'arguments sont séquencé. -la note de fin ]
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.9 Plusieurs contextes en C++ à cause de l'évaluation d'un appel de fonction, même en l'absence de correspondant en fonction de la syntaxe d'appel s'affiche dans l'unité de traduction. [ ... ]
Le séquençage des contraintes sur l'exécution de la fonction appelée (comme décrit ci-dessus) sont des caractéristiques de la fonction d'appels selon l'évaluation, quelle que soit la syntaxe de l'expression qui appelle la fonction peut être.

D'autres citations sont sur std::move

modèle typename remove_reference::type& de& move(T&& t) noexcept;
Retourne: static_cast::type&de&>(t).

Et std::unique_ptr<T>.operator->():

20.7.1.2.4 unique_ptr observateurs

pointeur operator->() const noexcept;
Nécessite: get() != nullptr.
Retourne: get().

memfunc obtient son argument par valeur, donc nous avons 3 appels:
a) obj->memfunc b) std::move(obj)
c) le constructeur de déplacement de l'argument passé.
Parce que b) ne pas changer quoi que ce soit, nous pouvons l'ignorer pour l'argument:

a et c sont pour une période indéterminée séquencé, ou peut être avant les autres.
Si une première, tout est bon, c changeant obj n'a pas d'importance.
Si c qui se passe en premier, est évaluée avec une remise à zéro obj, en violation de la condition, de sorte que nous avons UB.

En résumé, c'est un Comportement Indéfini, parce que l'un de ces ordres a un comportement indéfini.

18voto

Brian Points 15388

Oui, l'évaluation de l' x peut se produire avant, après, ou pendant l'évaluation de l' f (ils sont non).

[ Remarque: Les évaluations de la postfix expression et de l'argumentation expressions sont toutes non par rapport à une autre. Tous les effets secondaires de l'argument de l'expression des évaluations sont séquencée avant de la fonction est saisie (voir 1.9). - la note de fin ]

(C++11, §5.2.2/8)

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