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++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Responsable 2D/3D/Jeux


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

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 057
    Billets dans le blog
    142
    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 émérite
    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
    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
    27 057
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 057
    Billets dans le blog
    142
    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 confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 287
    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 287
    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
    27 057
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 057
    Billets dans le blog
    142
    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

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    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 202
    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.

  7. #7
    Membre émérite
    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
    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.

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

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