+ 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
    838
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 838
    Points : 577
    Points
    577

    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Expert Confirmé Sénior

    Avatar de Neckara
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2011
    Messages
    5 394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2011
    Messages : 5 394
    Points : 16 000
    Points
    16 000

    Par défaut

    Bonjour,

    Il me semble qu'il faut initialiser les static dans le .cpp :
    Code foo.h : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Foo
    {
      private:
        static const double forceMin;
        static const double forceMax;
    };

    Code foo.cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    838
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 838
    Points : 577
    Points
    577

    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 335
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : août 2004
    Messages : 2 335
    Points : 5 077
    Points
    5 077

    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
    838
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 838
    Points : 577
    Points
    577

    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
    Expert Confirmé Sénior

    Avatar de Neckara
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2011
    Messages
    5 394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2011
    Messages : 5 394
    Points : 16 000
    Points
    16 000

    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
    838
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 838
    Points : 577
    Points
    577

    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
    Expert Confirmé Sénior

    Avatar de Neckara
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2011
    Messages
    5 394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2011
    Messages : 5 394
    Points : 16 000
    Points
    16 000

    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 011
    Détails du profil
    Informations forums :
    Inscription : mai 2008
    Messages : 1 011
    Points : 2 205
    Points
    2 205

    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
    838
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 838
    Points : 577
    Points
    577

    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    838
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 838
    Points : 577
    Points
    577

    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
    838
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 838
    Points : 577
    Points
    577

    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
    Expert Confirmé Sénior

    Avatar de Neckara
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2011
    Messages
    5 394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2011
    Messages : 5 394
    Points : 16 000
    Points
    16 000

    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
    838
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 838
    Points : 577
    Points
    577

    Par défaut

    Citation Envoyé par Neckara Voir le message
    Code foo.cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Expert Confirmé Sénior

    Avatar de Neckara
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2011
    Messages
    5 394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2011
    Messages : 5 394
    Points : 16 000
    Points
    16 000

    Par défaut

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

    Code .cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    838
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 838
    Points : 577
    Points
    577

    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
    838
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 838
    Points : 577
    Points
    577

    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    ...has a previous declaration as...
    EDIT: en fait il fallait "répéter" le mot clef const, et là ça marche.
    Foo.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const double Foo::forceMin = 100.0;
    et non pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    s_forceMin;
    s_constForceMin;
    ...

  18. #18
    Expert Confirmé Sénior

    Avatar de Neckara
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2011
    Messages
    5 394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2011
    Messages : 5 394
    Points : 16 000
    Points
    16 000

    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
    838
    Détails du profil
    Informations forums :
    Inscription : avril 2007
    Messages : 838
    Points : 577
    Points
    577

    Par défaut

    Donc
    Foo.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // visible uniquement dans Foo.cpp
    static const double Foo::forceMin = 100.0;
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // je vois pas la difference 
    const double Foo::forceMin = 100.0;

  20. #20
    Expert Confirmé Sénior

    Avatar de Neckara
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2011
    Messages
    5 394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2011
    Messages : 5 394
    Points : 16 000
    Points
    16 000

    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
  •