Publicité
+ Répondre à la discussion
Page 1 sur 2 12 DernièreDernière
Affichage des résultats 1 à 20 sur 28
  1. #1
    Membre expérimenté Avatar de LinuxUser
    Inscrit en
    avril 2007
    Messages
    806
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 806
    Points : 506
    Points
    506

    Par défaut Initialisation variable membre static const double

    Bonjour,

    J'ai un problème d'initialisation d'une variable membre de type static const double, mais uniquemment sous Windows (Visual Studio) et pas sous Linux/MacOSX.

    Si on a la classe suivante:

    Code :
    1
    2
    3
    4
    5
    6
    class Foo
    {
      private:
        static const double forceMin = 100.0;
        static const double forceMax = 5000.0;
    };
    Sou Linux et MacOSX, aucun problème, alors que sous windows, ça ne compile pas et renvoie une erreur du style (j'ai plus le message exact):
    Code :
    can't initialize non-integral static const membre
    Sous Linux et MacOSX je choisis mes options de compilation, sous windows/VisualStudio parcontre c'est très obscure pour moi.

    J'ai pas compris le problème et pourquoi il apparait uniquement sous windows.

    Merci de votre aide.

  2. #2
    Responsable Sécurité

    Avatar de Neckara
    Homme Profil pro Denis
    Étudiant
    Inscrit en
    décembre 2011
    Messages
    4 646
    Détails du profil
    Informations personnelles :
    Nom : Homme Denis
    Âge : 21
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2011
    Messages : 4 646
    Points : 13 467
    Points
    13 467

    Par défaut

    Bonjour,

    Il me semble qu'il faut initialiser les static dans le .cpp :
    Code foo.h :
    1
    2
    3
    4
    5
    6
    class Foo
    {
      private:
        static const double forceMin;
        static const double forceMax;
    };

    Code foo.cpp :
    1
    2
    double Foo::forceMin = 100.0;
    double Foo::forceMax = 5000.0;

    EDIT : Après une simple recherche :
    Citation Envoyé par http://stackoverflow.com/questions/9656941/why-i-cant-initialize-non-const-static-member-or-static-array-in-class
    The C++ standard allows only static constant integral or enumeration types to be initialized inside the class.

  3. #3
    Membre expérimenté Avatar de LinuxUser
    Inscrit en
    avril 2007
    Messages
    806
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 806
    Points : 506
    Points
    506

    Par défaut

    OK, c'est ce que j'ai cru comprendre aussi, mais pourquoi sous Linux et MacOSX je n'ai pas eu de problème alors que j'initialise dans le .h.

  4. #4
    Expert Confirmé Sénior Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    août 2004
    Messages
    2 299
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : août 2004
    Messages : 2 299
    Points : 4 424
    Points
    4 424

    Par défaut

    En effet, j'ai l'erreur avec VS 2008.

    Pourtant en regardant la MSDN sur le code d'erreur C2864 Microsoft dit que ça devrait marcher. Ah non :

    Bon si tu remplaces double par int, ça marche. Il doit y avoir une restriction sur le type. Reste a savoir ce qu'est une donnée "intégrale".

  5. #5
    Membre expérimenté Avatar de LinuxUser
    Inscrit en
    avril 2007
    Messages
    806
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 806
    Points : 506
    Points
    506

    Par défaut

    Citation Envoyé par fregolo52 Voir le message
    Bon si tu remplaces double par int, ça marche.
    Ah nan, ça ça va pas être possible.
    Citation Envoyé par fregolo52 Voir le message
    Il doit y avoir une restriction sur le type.
    Dans les options de compilation de visual studio? D'ailleurs j'aimerai bien les connaitres.

    Citation Envoyé par fregolo52 Voir le message
    Reste a savoir ce qu'est une donnée "intégrale".
    C'est ce que je me demande également.

  6. #6
    Responsable Sécurité

    Avatar de Neckara
    Homme Profil pro Denis
    Étudiant
    Inscrit en
    décembre 2011
    Messages
    4 646
    Détails du profil
    Informations personnelles :
    Nom : Homme Denis
    Âge : 21
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2011
    Messages : 4 646
    Points : 13 467
    Points
    13 467

    Par défaut

    Citation Envoyé par fregolo52 Voir le message
    En effet, j'ai l'erreur avec VS 2008.

    Pourtant en regardant la MSDN sur le code d'erreur C2864 Microsoft dit que ça devrait marcher. Ah non :
    Il faudrait essayer avec mingw, il me semble que Microsoft avec Visual Studio ne voulait pas suivre entièrement le C++11 (?)

    Citation Envoyé par fregolo52 Voir le message
    Bon si tu remplaces double par int, ça marche. Il doit y avoir une restriction sur le type. Reste a savoir ce qu'est une donnée "intégrale".
    Une donnée "intégrale", ce n'est pas un entier (int abréviation de integer = intégrale) ?

  7. #7
    Membre expérimenté Avatar de LinuxUser
    Inscrit en
    avril 2007
    Messages
    806
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 806
    Points : 506
    Points
    506

    Par défaut

    Citation Envoyé par Neckara Voir le message
    Il faudrait essayer avec mingw, il me semble que Microsoft avec Visual Studio ne voulait pas suivre entièrement le C++11 (?)
    J'avais pensé installer et tester avec Cygwin, parcontre je savais pas que visual studio ne suivait pas entierement C++11, merci pour l'info.
    Citation Envoyé par Neckara Voir le message
    Une donnée "intégrale", ce n'est pas un entier (int abréviation de integer = intégrale) ?
    C'est ce que je me disait, mais pourquoi pas mettre integer dans ce cas?
    A moins qu'il y ait juste une différence subtile.

  8. #8
    Responsable Sécurité

    Avatar de Neckara
    Homme Profil pro Denis
    Étudiant
    Inscrit en
    décembre 2011
    Messages
    4 646
    Détails du profil
    Informations personnelles :
    Nom : Homme Denis
    Âge : 21
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2011
    Messages : 4 646
    Points : 13 467
    Points
    13 467

    Par défaut

    Citation Envoyé par LinuxUser Voir le message
    J'avais pensé installer et tester avec Cygwin, parcontre je savais pas que visual studio ne suivait pas entierement C++11, merci pour l'info.
    Il m'a semblé l'avoir lu mais je n'en suis pas sûr à 100%.

    Citation Envoyé par LinuxUser Voir le message
    C'est ce que je me disait, mais pourquoi pas mettre integer dans ce cas?
    A moins qu'il y ait juste une différence subtile.
    Integer fait référence à int et integral à tous les entiers de (unsigned) char à (unsigned)long long int ?

  9. #9
    Membre Expert

    Inscrit en
    mai 2008
    Messages
    1 006
    Détails du profil
    Informations forums :
    Inscription : mai 2008
    Messages : 1 006
    Points : 1 949
    Points
    1 949

    Par défaut

    Citation Envoyé par fregolo52
    Reste a savoir ce qu'est une donnée "intégrale".
    Citation Envoyé par LinuxUser
    C'est ce que je me demande également.
    Pour visualiser ce que recouvre l'ensemble des types "integral" :
    http://home.roadrunner.com/~hinnant/TypeHiearchy.pdf

    Edit : En C++03 seul les types const static "integral" et enum peuvent être initialisés dans la classe (dans le .h). Donc si ça marche pour les doubles avec GCC c'est probablement du à une extension, il faudrait essayer avec l'option -pedantic et voir si ça génère un warning.

  10. #10
    Membre expérimenté Avatar de LinuxUser
    Inscrit en
    avril 2007
    Messages
    806
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 806
    Points : 506
    Points
    506

    Par défaut

    Citation Envoyé par Arzar Voir le message
    Pour visualiser ce que recouvre l'ensemble des types "integral" :
    http://home.roadrunner.com/~hinnant/TypeHiearchy.pdf

    Edit : En C++03 seul les types const static "integral" et enum peuvent être initialisés dans la classe (dans le .h). Donc si ça marche pour les doubles avec GCC c'est probablement du à une extension, il faudrait essayer avec l'option -pedantic et voir si ça génère un warning.
    En effet tu as tout à fait raison, il me semblait avoir mis l'option -pedantic et en fait nan, je l'avais oublié.
    A présent cela génère l'erreur suivante:
    Code :
    1
    2
    3
     
    erreur: floating-point literal cannot appear in a constant-expression
    attention : ISO C++ forbids initialization of member constant ‘Foo::forceMax’ of non-integral type ‘const double[-pedantic]

  11. #11
    Membre expérimenté Avatar de LinuxUser
    Inscrit en
    avril 2007
    Messages
    806
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 806
    Points : 506
    Points
    506

    Par défaut

    Je dois donc initailiser mes membres dans le cpp plutôt alors.

  12. #12
    Membre expérimenté Avatar de LinuxUser
    Inscrit en
    avril 2007
    Messages
    806
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 806
    Points : 506
    Points
    506

    Par défaut

    Je dois donc initailiser mes membres static const double dans le constructeur dans le cpp alors.

    Moi je trouvais cela mieux de les initialiser directement dans le .h plutot que dans le constructeur.

  13. #13
    Responsable Sécurité

    Avatar de Neckara
    Homme Profil pro Denis
    Étudiant
    Inscrit en
    décembre 2011
    Messages
    4 646
    Détails du profil
    Informations personnelles :
    Nom : Homme Denis
    Âge : 21
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2011
    Messages : 4 646
    Points : 13 467
    Points
    13 467

    Par défaut

    Citation Envoyé par LinuxUser Voir le message
    Je dois donc initailiser mes membres static const double dans le constructeur dans le cpp alors.

    Moi je trouvais cela mieux de les initialiser directement dans le .h plutot que dans le constructeur.
    On initialise pas les variables statique (et surtout const) dans un constructeurs.

    Cf mon premier post.

  14. #14
    Membre expérimenté Avatar de LinuxUser
    Inscrit en
    avril 2007
    Messages
    806
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 806
    Points : 506
    Points
    506

    Par défaut

    Citation Envoyé par Neckara Voir le message
    Code foo.cpp :
    1
    2
    double Foo::forceMin = 100.0;
    double Foo::forceMax = 5000.0;
    Oui c'est vrai, je n'avais pas vu.
    Mais de le .cpp, tu fais cette initialisation où? Tout au début, en dehors de tout alors (comme une varible globale)?

  15. #15
    Responsable Sécurité

    Avatar de Neckara
    Homme Profil pro Denis
    Étudiant
    Inscrit en
    décembre 2011
    Messages
    4 646
    Détails du profil
    Informations personnelles :
    Nom : Homme Denis
    Âge : 21
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2011
    Messages : 4 646
    Points : 13 467
    Points
    13 467

    Par défaut

    C'est comme lorsque tu implémentes une méthode de ta classe.

    Code .cpp :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Foo::Foo(void)
    {
    }
     
    bool Foo::fooo(void)
    {
          return m_fooo;
    }
     
    bool Foo::m_fooo = true;

  16. #16
    Membre expérimenté Avatar de LinuxUser
    Inscrit en
    avril 2007
    Messages
    806
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 806
    Points : 506
    Points
    506

    Par défaut

    D'accord, j'ai compris, je vais tester à présent.

  17. #17
    Membre expérimenté Avatar de LinuxUser
    Inscrit en
    avril 2007
    Messages
    806
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 806
    Points : 506
    Points
    506

    Par défaut

    Ca ne marche pas, le compilateur considère que dans le .cpp j'essaye de définir une seconde fois une varible qui existe déjà:
    Code :
    ...has a previous declaration as...
    EDIT: en fait il fallait "répéter" le mot clef const, et là ça marche.
    Foo.cpp
    Code :
    const double Foo::forceMin = 100.0;
    et non pas :
    Code :
    double Foo::forceMin = 100.0;
    Dans ce cas, pourquoi ça râle pas pour le mot clef static que je n'est pas "répété" ?

    Je rappelle le Foo.h
    Code :
    1
    2
    3
    4
    5
    class Foo
    {
    private:
      static const double forceMin;
    };
    Petite question subsidiaire, comment préfixeriez-vous cette varible membre pour indiquer qu'il s'agit d'un static const?
    Code :
    1
    2
    3
    s_forceMin;
    s_constForceMin;
    ...

  18. #18
    Responsable Sécurité

    Avatar de Neckara
    Homme Profil pro Denis
    Étudiant
    Inscrit en
    décembre 2011
    Messages
    4 646
    Détails du profil
    Informations personnelles :
    Nom : Homme Denis
    Âge : 21
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2011
    Messages : 4 646
    Points : 13 467
    Points
    13 467

    Par défaut

    Pour le const c'est de ma faute désolé

    Pour le static, il peut avoir 3 effets/signification.
    Si tu le rajoutes à l'extérieur de ta classe, tu vas dire que ta variable ne peut être visible que dans le fichier où tu l'a déclaré.

    Sinon pour la préfixé, je ne mettrait que m_machin pour dire que c'est un membre, mais pas plus.

  19. #19
    Membre expérimenté Avatar de LinuxUser
    Inscrit en
    avril 2007
    Messages
    806
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 806
    Points : 506
    Points
    506

    Par défaut

    Donc
    Foo.cpp
    Code :
    1
    2
    // visible uniquement dans Foo.cpp
    static const double Foo::forceMin = 100.0;
    et
    Code :
    1
    2
    // je vois pas la difference 
    const double Foo::forceMin = 100.0;

  20. #20
    Responsable Sécurité

    Avatar de Neckara
    Homme Profil pro Denis
    Étudiant
    Inscrit en
    décembre 2011
    Messages
    4 646
    Détails du profil
    Informations personnelles :
    Nom : Homme Denis
    Âge : 21
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2011
    Messages : 4 646
    Points : 13 467
    Points
    13 467

    Par défaut

    La différence est assez simple :
    erreur : 'static' may not be used when defining (as opposed to declaring) a static data member [-fpermissive]
    Un membre doit être visible dans toute la classe, et non pas être visible dans un seul fichier.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •