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

Langage C++ Discussion :

Tableau static, sizeof et taille déterminée à la compilation


Sujet :

Langage C++

  1. #1
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut Tableau static, sizeof et taille déterminée à la compilation
    Bonjour à tous,

    Voici le programme minimaliste de test pour mon problème :
    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
    #include <iostream>
     
    const char* Test::pC[] = { "lol", "lil", "lul" };
    static class Test
    {
    public:
       static const char* pC[];
    }
     
    int main()
    {
       std::cout << "Array size is : " << sizeof(Test::pC)/sizeof(char*) << std::endl;
     
       return 0;
    }
    Il ne compile pas, car :
    main.cpp:12:54: error: invalid application of ‘sizeof’ to incomplete type ‘const char* []’
    Si j'enlève ma classe, tout va bien.

    Je comprend qu'une variable statique dans une classe, sera initialisée avant l'appel au main. Du coup, le code remplissant mon tableau, c'est pas vraiment interprété par le compilateur et donc, il n'est pas capable de dire quelle est la taille réelle du tableau. Pourtant, la syntaxe est juste en soit.

    Je ne comprend pas vraiment ce comportement. Je vois bien que la taille du tableau ne peut être déterminée que lors de l'exécution, mais alors, cette syntaxe, comment se fait t-elle qu'elle soit juste ?

    Pouvez-vous me détailler tout le comportement du compilateur dans un tel cas et pour j'ai ce message d'erreur ?
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  2. #2
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Points : 1 211
    Points
    1 211
    Par défaut
    static class ?
    Tu as réussi à définir Test::pC avant Test ?!!
    Et ça compile quand la classe Test n'est pas définie ?!

  3. #3
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Ah purée. Vous avez mis le point sur quelque chose.

    Ok, le static class était complètement faux.
    Il faut bien mettre l'initialisation après la classe.

    Par contre, si on déplace l'initialisation dans un autre fichier (par exemple, dans un CPP, comme Test.cpp), l'erreur revient. Par contre, si on laisse bien l'initialisation après la classe, il n'y a aucun souci. Mais je n'arrive pas à très bien comprendre la raison.
    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
    #include <iostream>
     
    class Test
    {
    public:
       static const char* pC[];
    };
    const char* Test::pC[] = { "lol", "lil", "lul" };
     
    int main()
    {
       std::cout << "Array size is : " << sizeof(Test::pC)/sizeof(char*) << std::endl;
     
       return 0;
    }
    Le souci, c'est si je mets Test dans un HPP, avec son initialisation, il va me dire qu'il est défini plusieurs fois dans mon code (si je l'inclue plusieurs fois )
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  4. #4
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Je sais que ce n'est pas la question, mais puis-je suggérer de bannir le sizeof/sizeof en C++ pour privilégier std::extent<decltype(Tab)>::value ou ce genre de chose ?
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  5. #5
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    La proposition est juste mais pour ce projet, je ne suis pas sensé être en C++11, pour des raisons de compatibilité.
    Mon objectif, c'est juste avoir un tableau de chaines de caractères, statique et unique et en dur, dans le code, car ce n'est qu'une liste de variable de configuration.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  6. #6
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Tu n'a qu'a avoir sa taille en dur aussi.

    Quant à l'initialisation, il faut la mettre dans un quelconque .cpp.

    Cela dit, si ce n'est effectivement utile qu'en interne de la classe, tu peux carrément mettre le tableau en variable globale, mais confinée au .cpp de la classe via un namespace anonyme.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  7. #7
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Points : 1 211
    Points
    1 211
    Par défaut
    Il me semble que ça suit un peu la logique des structures.

    Pour instancier une structure (ou classe), il faut absolument sa définition, faute de quoi on ne peut pas savoir quelle est la taille de l'objet instancié, ni l'interface qu'il nous fournit. Par contre, on peut très bien forward declare cette classe ( class Test; ) est utiliser un pointeur : le pointeur a une taille fixe (égale à sizeof(void*)) et sauf déréférencement (*p ou p->) on ne manipule pas l'objet pointé en soi, donc on a pas besoin de la définition de sa classe.

    Pour déterminer la taille d'un tableau, sizeof() a besoin de savoir combien d'éléments ce tableau contient (logique, non ?). Or lors d'une déclaration du style
    T array[] = { /*... */ };
    le compilateur peut effectivement déterminer la taille du tableau grâce à la liste qui lui est passée.
    Si cette liste n'est pas définie avant le sizeof() dans la même unité de compilation (le même fichier quoi), alors tout ce que le compilo sait c'est que array est un tableau, mais il ne connaît pas sa taille. Il connaît le type du tableau, et te permet donc de le manipuler à ta guise, mais pas sa taille. D'où l'erreur "type incomplet" ; le compilo connait l'interface (comment utiliser le tableau) mais pas son contenu : un peu comme lorsqu'on utilise un pointeur sur une classe non définie.

    Remarque : le sizeof() d'un tableau est déterminé à la compilation, puisqu'une fois compilé il n'y a plus rien qui puisse permettre de déterminer sa taille : le compilateur ne stocke pas d'informations supplémentaires.

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Tu as le même problème sans classe (ou en C): Tu ne peux pas obtenir la taille d'un tableau global si elle n'est pas spécifiée dans l'unité de compilation courante:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    //Tableau.cpp
    #include <iostream>
     
    const int g_Tableau[] = {1, 2, 3}; //Ceci spécifie la taille du tableau
     
    void testDansSource()
    {
    	std::cout << sizeof(g_Tableau) << std::endl; //Ici, ça marche
    }
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //Main.cpp
    #include <iostream>
     
    extern const int g_Tableau[]; //Ceci ne spécifie pas la taille
    void testDansSource();
     
    int main(void)
    {
    	testDansSource();
    	std::cout << sizeof(g_Tableau) << std::endl; //Ici, ça ne marche pas.
    	return 0;
    }



    Edit: D'ailleurs, je suppose qu'une "constante" externe n'est plus qu'une "variable const", et ne compte plus comme "constante connue à la compilation" (puisqu'au mieux, elle n'est connue qu'à l'édition de liens).

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //Tableau.cpp
    #include <iostream>
     
    const int g_Tableau[] = {1, 2, 3}; //Ceci spécifie la taille du tableau
    const size_t g_tailleTableau = sizeof g_Tableau / sizeof g_Tableau[0];
     
    void testDansSource()
    {
    	std::cout << sizeof(g_Tableau)/sizeof(int) << "=" << g_tailleTableau << std::endl; //Ici, ça marche
    	//Je pense qu'ici, g_tailleTableau est une constante connue à la compilation
    	//(bonne pour template, tableau, switch...)
    }
    Code C++ : 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
    //Main.cpp
    #include <iostream>
     
    extern const int g_Tableau[]; //Ceci ne spécifie pas la taille
    extern const int g_tailleTableau;
    void testDansSource();
     
    int main(void)
    {
    	testDansSource();
    	std::cout <<  g_tailleTableau << std::endl; //Ceci marche, mais:
    	//g_tailleTableau ne peut pas dimensionner un tableau
    	//g_tailleTableau ne peut pas être paramètre d'un template
    	//g_tailleTableau ne peut pas être un case.
    	return 0;
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Citation Envoyé par LittleWhite Voir le message
    La proposition est juste mais pour ce projet, je ne suis pas sensé être en C++11, pour des raisons de compatibilité.
    Mon objectif, c'est juste avoir un tableau de chaines de caractères, statique et unique et en dur, dans le code, car ce n'est qu'une liste de variable de configuration.
    D'où la seconde façon de procéder que je donnais en lien. Et que je mixe régulièrement avec des enums (et ce même avec gcc 2.95.3!) pour vérifier qu'il y a autant de chaines que d'éléments dans mon enum via une assertion statique (boost/loki).
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  10. #10
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Oui, j'ai vu Luc Hermitte, mais cela me semblait un peu trop tendu pour le simple problème que j'avais.

    La solution, je viens de la deviner (bon, avec votre aide et celle de mes collègues) :
    Vous, avez trois fichiers :
    Defs.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    class Test
    {
    public:
       static const char* pC[];
       static const size_t size;
    };
    Defs.cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    const char* Test::pC[] = { "lol", "lil", "lul" };
    const size_t Test::size = sizeof(Test::pC)/sizeof(*Test::pC);
    Et dans votre main.cpp, vous utilisez le tableau et sa taille. Je règle ainsi le souci de compilation avec sizeof(), car comme le sizeof() est effectué dans la même unité de compilation, il connait la taille effective de mon tableau.
    J'ai réglé le soucis des multiples definition, car j'ai bien une séparation déclaration/initialisation.

    On notera par contre, que la variable size, étant dans une unité de compilation différente, ne pourra pas bénéficier de toutes les optimisations liée aux variables constantes, car elle sera résolue que à l'édition de lien. Il faudrait, pour en bénéficier, rajouter un -flto.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  11. #11
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Que penses-tu de ceci?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef std::vector<std::string>::const_iterator option_iterator;
     
    //you should loop from options() to not_an_option()
    option_iterator options();
    option_iterator not_an_option();
    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
    namespace {
    template <typename T>
    std::vector<T>& operator<<(std::vector<T>& those, T const& that) {
        those.push_back(that);
        return those;
    }
     
    std::vector<std::string> options = std::vector<std::string>()<<"un"<<"deux"<<"trois";
    }
     
    std::vector<std::string>::const_iterator options() {
        return options.begin();
    }
     
    std::vector<std::string>::const_iterator not_an_option() {
        return options.end();
    }
    Du coup, dans main, on aura ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int main() {
        cout << "option disponibles:"<<endl;
        for(option_iterator it = options(); it!=not_an_option(); ++it) {
            cout <<*it<<endl;
        }
        return 0;
    }
    PS: si jamais ça ne compile pas, jette un œil sur boost::initializer
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  12. #12
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Je trouve que c'est un peu overkill pour ce que je souhaitais
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  13. #13
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Disons que la solution C à base de sizeof a vite fait de renvoyer des erreurs car elle m'impose pas la précondition que tu as sur ton expression -> précondition pour obtenir le nombre d'élément d'un tableau : que le truc évalué soit bien un tableau et pas autre chose parce que nous ne serions pas dans la même unité de traduction, ou autre.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  14. #14
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Oui, mais bon, que faire de plus, dans un tel cas ? Et puis, n'allons nous pas trop loin dans la sécurisation ?
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  15. #15
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    overkill? un vecteur et pas de variable globale apparente.

    Et en C++11, ca serait plus simple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    namespace {
    std::vector<std::string> options = {"un", "deux", "trois"};
    }//::
     
    std::vector<std::string>::const_iterator options() {
        return options.begin();
    }
     
    std::vector<std::string>::const_iterator not_an_option() {
        return options.end();
    }
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  16. #16
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par LittleWhite Voir le message
    Oui, mais bon, que faire de plus, dans un tel cas ? Et puis, n'allons nous pas trop loin dans la sécurisation ?
    Étant donné que ton tableau est constant, je suis du même avis que leternel, fixer à la main la taille size_t Test::size = 3
    Par contre niveau maintenance il faut avoir confiance

    L'autre truc c'est enum { OPTION1 = 0, OPTION2, OPTION3, /* ... */ NB_OPTIONS};.
    Et ensuite size_t Test::size = NB_OPTIONS

  17. #17
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Citation Envoyé par LittleWhite Voir le message
    Oui, mais bon, que faire de plus, dans un tel cas ? Et puis, n'allons nous pas trop loin dans la sécurisation ?
    Vu la simplicité de la chose (un #include à charger), certainement pas.

    Citation Envoyé par foetus Voir le message
    Étant donné que ton tableau est constant, je suis du même avis que leternel, fixer à la main la taille size_t Test::size = 3
    Par contre niveau maintenance il faut avoir confiance
    Là, c'est une mauvaise solution. Au premier refactoring, l'enum et le tableau sont facilement désynchronisés. L'ordre demande de l'attention, mais le nombre d'éléments peut être vérifié par le compilateur.
    La solution (§4.1) que je préconise a le mérite d'être simple et robuste -- au détail qu'il faille utiliser une macro et non std::extent en C++98/03.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  18. #18
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Points : 1 211
    Points
    1 211
    Par défaut
    Citation Envoyé par foetus Voir le message
    Étant donné que ton tableau est constant, je suis du même avis que leternel, fixer à la main la taille size_t Test::size = 3
    Par contre niveau maintenance il faut avoir confiance
    On pourrait générer une erreur de compilation quand Test::size != sizeof (Test::pC) / sizeof (*Test::pC) ...

  19. #19
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Je préfère quand même utiliser des nombres non signés et commencer mon énumération à zéro, au lieu de faire un tas de grigis (surtout avec des nombres négatifs à moins qu'il y ait une feinte)


    Citation Envoyé par the Hound Voir le message
    On pourrait générer une erreur de compilation quand Test::size != sizeof (Test::pC) / sizeof (*Test::pC) ...
    Est-tu sûr que ton sizeof marche partout avec un tableau?

    Je préfère le coup de l'enum qui s'il n'est pas désynchronisé est plus simple, et permet même de se passer de cet attribut size

  20. #20
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Points : 1 211
    Points
    1 211
    Par défaut
    Citation Envoyé par foetus Voir le message
    Est-tu sûr que ton sizeof marche partout avec un tableau?
    Non, uniquement là où le contenu du tableau est défini. (Mais une condition à cet endroit là permettrait de faire échouer l'ensemble de la compilation.)

    Je préfère le coup de l'enum qui s'il n'est pas desynchronisé est plus simple, et permet même de se passer de cet attribut size
    Et après on vient me parler de maintenance ma proposition était un pur troll

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

Discussions similaires

  1. Tableau static
    Par raynox dans le forum C++
    Réponses: 15
    Dernier message: 27/04/2006, 08h22
  2. [Débutant(e)][embarqué] Base de données vs tableau static
    Par ludonantes dans le forum Collection et Stream
    Réponses: 16
    Dernier message: 15/02/2006, 20h42
  3. ouvrir une nouvelle fenêtre dans une taille déterminé
    Par lnikolanta dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 26/09/2005, 15h26
  4. [Tableau]comment connaitre la taille d'un tableau à 2 dimensions
    Par Kyti dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 22/04/2005, 10h27
  5. static const et taille de tableau
    Par tut dans le forum C++
    Réponses: 3
    Dernier message: 27/01/2005, 16h01

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