IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Ordre d'initialisation des attributs


Sujet :

C++

  1. #1
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut Ordre d'initialisation des attributs
    Hello,

    J'ai remarqué ya quelques temps que gcc se plaignait lorsque l'ordre d'initialisation des attributs dans le constructeur était différent de l'ordre de déclaration des attributs dans la classe / struct.

    Cela veut-il dire qu'un attribut déclaré avant un autre sera initialisé avant un autre, et pourra dont être utilisé pour initialisé un autre attribut ?

    Un petit exemple pour mieux expliquer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    struct Foo {
    	const int val;
     
    	Foo(int v=42): val(v) { }
    	Foo(const Foo& foo): val(foo.val) { }
    };
     
    struct Bar {
    	const Foo a;
    	const Foo b;
     
    	Bar(int val):
    		a(val),
    		b(a) // ok car a déclaré avant dans Bar ?
    		// mais serait faux si b déclaré avant a dans la struct ?
    	{ }
    };

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Dans le cas que tu présentes, ne serait-il pas clair d'initialiser b à l'aide de val ?

    Je te suggère de tester par toi-même, avec deux membres de type différent, dont le second prend dans le constructeur le premier.

  3. #3
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par oodini Voir le message
    Dans le cas que tu présentes, ne serait-il pas clair d'initialiser b à l'aide de val ?
    Oui bien sur, j'avais pas envie de faire un exemple trop long, mais le principe reste le même.

    Citation Envoyé par oodini Voir le message
    Je te suggère de tester par toi-même, avec deux membres de type différent, dont le second prend dans le constructeur le premier.
    Justement ça "à l'air de marcher", c'est pour ça que je voudrais la confirmation que c'est safe, ou savoir si c'est un comportement indéfini qui marche ici mais qui pourrait ne plus marcher sur une prochaine version d'un compilo par exemple.

  4. #4
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Il me semble que la question a déjà été posée et que ce comportement est demandé par la norme (ce qui veut pas dire qu'il est garanti par tous les compilateurs ) Par contre, comme toujours dans ce cas, pas moyen de retrouver
    Voir peut être la norme ?

  5. #5
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    Voir peut être la norme ?
    J'aurais du rechercher la dedans directement oui

    Citation Envoyé par C++ standard 12.6.2 class.base.init p5
    Initialization shall proceed in the following order:
    — First, and only for the constructor of the most derived class as described below, virtual base classes shall be initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base class names in the derived class base-specifier-list.
    — Then, direct base classes shall be initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).
    — Then, nonstatic data members shall be initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).
    — Finally, the body of the constructor is executed.
    [Note: the declaration order is mandated to ensure that base and member subobjects are destroyed in the reverse order of initialization. ]
    C'est donc bien un comportement défini correctement.

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,
    Cela veut-il dire qu'un attribut déclaré avant un autre sera initialisé avant un autre, et pourra dont être utilisé pour initialisé un autre attribut ?
    A priori, oui, d'après la norme.

    D'après la norme, les différents éléments sont initialisés dans un ordre clair et précis:
    1. Les classes de base, dans l'ordre de la déclaration d'héritage
    2. Les attributs membre, dans l'ordre de leur déclaration (indépendamment de leur visibilité).

    Comme tout objet correctement initialisé peut, a priori, être utilisé pour en initialiser un autre, il n'y a, a priori toujours, aucune objection au fait qu'un membre initialisé en premier serve à initialiser un autre membre

    L'avertissement auquel tu es confronté t'indique que tu risques de ne pas observer ce comportement normal si tu essayes d'initialiser les différents membres dans l'ordre imparti

    Dans 90% des cas, cet avertissement ne posera sans doute aucun problème, mais comme il est sommes toutes relativement aisé d'y apporter une solution, c'est sans doute aussi le genre d'avertissement auquel on sera attentif
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Dans 90% des cas, cet avertissement ne posera sans doute aucun problème, mais comme il est sommes toutes relativement aisé d'y apporter une solution, c'est sans doute aussi le genre d'avertissement auquel on sera attentif
    C'est justement grâce à la présence de c'est avertissement que je me posais la question.
    J'avais déjà eu des cas de seg fault à cause du non respect de l'ordre (sur Visual Studio, qui ne donne pas ce warning ), du coup j'évitais tout simplement la situation depuis.

  8. #8
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Oui, c'est effectivement le genre de situation assez désagréable dont il est difficile de trouver la raison si l'on ne dispose pas au minimum d'un avertissement.

    Je crois cependant que le même code (comprends: comportant la même erreur) ne provoquerait (à ma connaissance) pas forcément une erreur de segmentation sous Gcc (qui présente quand meme un meilleur support de la norme que VS )

    Ceci dit, je ne suis pas loin de penser qu'il faut vraiment de très bonnes raisons pour en arriver à ce que l'initialisation d'un membre dépende de celle d'un membre précédemment effectuée.

    Je ne vais pas (pour une fois) crier au problème de conception, mais je ne trouve malgré tout pas forcément cette situation très saine

    Ce n'est, bien sur qu'un avis strictement personnel, mais je me demande dans quelle mesure cette situation ne met pas en évidence le fait que les deux membres visés soient particulièrement (trop ) dépendants les un des autres. Partant de là, il me semble "logique" de craindre un certain nombre de problèmes dus, justement, à cette dépendance trop importante
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Initialisation des attributs d'un slider à partir de données chargées dynamiquement.
    Par Drannor dans le forum Windows Presentation Foundation
    Réponses: 6
    Dernier message: 01/03/2012, 14h55
  2. Réponses: 16
    Dernier message: 09/08/2010, 11h14
  3. Réponses: 9
    Dernier message: 21/03/2010, 21h42
  4. [SSAS] [2K5] Ordonner l'ordre d'affichage des attributs
    Par stephane.net dans le forum SSAS
    Réponses: 0
    Dernier message: 19/10/2009, 11h59
  5. [POO] initialiser des attributs
    Par poukill dans le forum C++
    Réponses: 6
    Dernier message: 26/07/2006, 11h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo