Liaison d'une référence Const à un sous-objet temporaire : une énigme
L'extrait de code C ci-dessous démontre une différence de comportement entre les différents compilateurs lorsque vous tentez de lier une référence const à un sous-objet d'un temporaire :
<code class="cpp">#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; // Bind a reference to temporary's x member printf("x = %.18g\n", x); // Expected: 10 return 0; }</code>
Bogue ou comportement attendu ?
Les compilateurs comme g mettent fin à la durée de vie du instance P2d temporaire avant d'entrer le printf dans main, mais la valeur du membre double x est toujours conservée. Ceci est réalisé en créant un autre double temporaire pour copier la valeur au lieu de la lier au membre temporaire d'origine.
D'un autre côté, clang prolonge correctement la durée de vie du temporaire P2d pour correspondre à celle de la référence x, permettant le destructeur à appeler après le printf dans main.
Cette divergence pose la question : le comportement de g est-il un bug ou est-il autorisé selon la norme C ?
Analyse et solution
CWG 1651 met en lumière ce problème :
La liaison d'une référence à un sous-objet ne doit pas prolonger la durée de vie des objets temporaires.
Selon les normes actuelles, les objets autres que les scalaires, tels que les classes ou les tableaux, peuvent prolonger la durée de vie de l'objet temporaire.
Comportement du compilateur
Conclusion
Sur la base de la formulation actuelle de la norme C, le comportement de GCC est techniquement correct, tandis que l'implémentation de Clang reflète les modifications proposées dans le DR 1651. Il est probable que la norme sera révisée pour refléter ce changement à l'avenir.
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!