Maison  >  Article  >  développement back-end  >  La liaison d'une référence Const à un sous-objet temporaire en C est-elle un bug ou un comportement attendu ?

La liaison d'une référence Const à un sous-objet temporaire en C est-elle un bug ou un comportement attendu ?

Linda Hamilton
Linda Hamiltonoriginal
2024-10-26 11:26:29822parcourir

Is Binding a Const Reference to a Temporary Sub-Object in C   a Bug or Expected Behavior?

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

  • GCC : prolonge la durée de vie uniquement pour les sous-objets de classe ou de tableau, sur la base de la résolution CWG 1651.
  • Clang : implémente déjà les règles d'extension de durée de vie décrites dans N3918, ce qui prolonge la durée de vie de tous les sous-objets temporaires.

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn