Considérez l'extrait de code suivant :
<code class="c++">#include <stdio.h> struct P2d { double x, y; P2d(double x, double y) : x(x), y(y) {} ~P2d() { printf("Destructor called\n"); } }; P2d center() { return P2d(10, 10); } int main(int argc, const char *argv[]) { const double& x = center().x; printf("x = %.18g\n", x); return 0; }</code>
Quand compilée avec GCC 5.2.0, l'instance temporaire P2d est détruite avant d'entrer l'appel printf dans main. Malgré cela, la valeur de x est conservée et imprimée correctement. En d'autres termes, au lieu de lier x directement au membre x du temporaire P2d, un deuxième double temporaire est créé pour copier la valeur du membre.
D'autre part, Clang étend la durée de vie du temporaire P2d à la durée de vie de la référence x, ce qui entraîne l'appel du destructeur après le printf dans main.
Cela soulève la question : ce comportement est-il un bug dans GCC ou est-il autorisé par la norme ?
CWG 1651 résout ce problème :
The resolution of issues 616 and 1213, making the result of a member access or subscript expression applied to a prvalue an xvalue, means that binding a reference to such a subobject of a temporary does not extend the temporary's lifetime. [class.temporary] should be revised to ensure that it does.
Actuellement, [class.temporary]/5 déclare : "Le deuxième contexte est celui où une référence est liée à un temporaire. " Cela a été interprété comme s'appliquant uniquement aux références qui se lient directement aux objets temporaires. Par conséquent, dans l'extrait de code ci-dessus, center().x est traité comme une valeur prédéfinie (à la fois par Clang et GCC), et [class.temporary]/5 n'est pas applicable.
Cependant, GCC et Clang ont pas encore mis en œuvre la résolution du DR 1651, qui est N3918. Cette résolution indique explicitement que « les expressions d'accès aux membres et d'indice appliquées à une expression temporaire génèrent des expressions temporaires » et ajoute que « l'objet temporaire correspondant (le cas échéant) persiste pendant toute la durée de vie de la référence. »
Ainsi, sur la base du libellé de N3918, il semble que Clang implémente le comportement prévu, alors que GCC ne l'est pas. DR 60297 note que GCC ne prolonge pas la durée de vie des sous-objets scalaires des temporaires, car ils ne sont pas couverts par [dcl.init.ref]/(5.2.1.1).
En résumé, le comportement actuel dans GCC est correct selon le libellé actuel de la norme, mais la norme sera probablement révisée pour exiger une prolongation de la durée de vie dans ce cas. Clang met déjà en œuvre le comportement futur attendu.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!