Est-il légal de passer un objet C dans son propre constructeur ?
Il est déroutant qu'un code comme celui-ci semble fonctionner :
#include <iostream> struct Foo { Foo(Foo& bar) { std::cout << &bar << std::endl; } }; int main(int argc, char** argv) { Foo foo(foo); // I can't believe this works... std::cout << &foo << std::endl; // but it does... return 0; }
En passant l'adresse d'un objet non initialisé dans son propre constructeur, nous semblons établir une définition circulaire. La question se pose : les standards permettent-ils de passer un objet à une fonction avant sa construction ? Ou cela constitue-t-il un comportement indéfini ?
Légal, mais pas rare
Transmettre l'adresse d'un objet non initialisé à son propre constructeur n'est pas un comportement indéfini. Bien que foo ne soit pas initialisé, nous l'utilisons d'une manière approuvée par les normes.
L'allocation de mémoire d'objet se produit avant l'initialisation complète. Par conséquent, lier une référence à une telle variable et récupérer son adresse est autorisé pendant cet intervalle.
Ce comportement est conforme au rapport de défauts 363, qui précise que les références créées dans une telle situation sont considérées comme valides. La section 3.8 [basic.life] de la norme C 14 précise en outre que l'utilisation de valeurs gl faisant référence à des objets alloués mais non initialisés est admissible dans certaines limites.
À savoir, nous ne pouvons pas appliquer de conversions lvalue en rvalue, accéder à des valeurs non statiques. données membres ou invoquer des fonctions membres non statiques, se lier à des références de classe de base virtuelle ou utiliser Dynamic_cast ou typeid.
Dans notre exemple, nous évitons ces actions interdites, en liant une référence et en acquérant l'adresse.
Avertissements du compilateur
Malgré la légitimité du comportement, Clang émet un avertissement :
warning: variable 'foo' is uninitialized when used within its own initialization [-Wuninitialized]
Cet avertissement est justifié puisque la génération d'une valeur indéterminée à partir d'un fichier non initialisé la variable automatique constitue un comportement indéfini. Néanmoins, notre utilisation ne donne pas de valeur indéterminée et est donc légale.
Considérations supplémentaires
Bien que l'auto-initialisation en passant un objet à son propre constructeur ne soit pas intrinsèquement bénéfique ou conseillé, cela peut être une méthode intéressante pour explorer le comportement de classe. Cependant, l'auto-initialisation par affectation, comme dans int x = x;, constitue un comportement indéfini.
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!