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 :

sizeof(rien_du_tout) == 1


Sujet :

Langage C++

  1. #1
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut sizeof(rien_du_tout) == 1
    Je ne m'étais jamais posé la question de savoir combien de place une structure (ou classe) dépourvue d'attribut prenait de place en mémoire. Spontanément j'aurais dit "zéro" si on m'avait posé la question sans prendre le temps de vérifier ou réfléchir.

    Ainsi donc les traits, par exemple, ou bien d'autre classes de la STL ne servant qu'à faire du "typage", sont vides et pourtant leur sizeof() est égal à 1.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct rien_du_tout { };
    cout << "résultat: " << sizeof(rien_du_tout) << endl;
     
    résultat: 1
    C'est curieux.
    Mais par ailleurs, si sizeof()==0, comment instantier un objet de rien_du_tout ? Comment imaginer le comportement d'un pointeur vers un emplacement en mémoire d'une instance de rien_du_tout ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct un_peu: rien_du_tout { char c; };
    cout << "résultat: " << sizeof(un_peu) << endl;
     
    résultat: 1
    Bon, soit...

    Mais ça m'embête un peu. J'aimerais quand même que sizeof(rien_du_tout)==0.
    Prenons par exemple le cas d'un list< vector<int> > ou d'un list< string > où on consomme de la mémoire "en trop" pour rien. En cause std::allocator qui est une classe "vide" (sous Visual en tout cas) mais qui est "instanciée" dans chaque vector, dans chaque string aussi (et dans tous les conteneurs en général). Et pour peu que l'on fasse un alignement en mémoire (c'est le cas par défaut) on perd 4 octets à chaque instance. C'est cher payé pour "rien".

    Pour une fois on aimerait bien que std::allocator soit instanciée une bonne fois pour toute dans une variable globale, d'autant plus que les allocators autre que le standard ne sont pas légions. Dans Loki je crois qu'il y a un SmallObjectAllocator, c'est le seul autre que je connaisse.
    J'ai aussi déjà posé la question sur le forum afin de savoir si quelqu'un s'était lancé dans l'écriture d'un allocator, ou les régles à respecter pour le faire. Sans beaucoup de succès...

    Bref, pourquoi sizeof(rien_du_tout)==1 et non pas 0 ?

  2. #2
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  3. #3
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Tient, j'avais posé la même question il y a 1 an : Taille des classes, question à 0,01€
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Si tu hérites d'une classe vide, alors ça n'augmente pas la taille sur la plupart des compilateurs.
    C'est comme ça que les conteneurs font pour les allocateurs.

    Voir aussi boost::compressed_pair.
    Boost ftw

  5. #5
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Merci.
    Je me doutais bien que la réponse était "simplement" dans la distinction d'une instance d'une autre (surtout dans un tableau).

    Après réflexion, je me demande si l'argumentation n'est pas un peu faible car finalement l'instantiation d'un contenu vide n'a pas beaucoup de sens. Enfin si, elle a du sens, ce qui n'en a pas c'est de lui attribuer de l'espace mémoire. Ainsi sous le simple prétexte que, par impossible, un programmeur chercherait à distinguer une instance vide d'une autre (ça vous arrive souvent, vous ?), allez, hop, un peu de mémoire inutile consommée pour tout le monde.

    Je préfèrerais que sizeof(rien_du_tout)==0. Et, le cas échéant, le compilateur pourrait générer un warning (ou même une erreur) lorsque le code cherche à repérer l'espace mémoire que l'instance occuperait.
    Je ne verrais donc pas d'inconvénient à ce que le compilateur refuse des écritures comme celles-ci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::vector<rien_du_tout> v;
    rien_du_tout arr[25];

  6. #6
    Membre éclairé

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Points : 858
    Points
    858
    Par défaut
    Si sizeof(rien_du_tout)==0, la question que je me poserai c'est quel est l'intérêt de rien_du_tout, puisque ce n'est rien du tout, autan ne rien utiliser du tout ?

  7. #7
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Un type vide a beaucoup d'utilités.
    Boost ftw

  8. #8
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Un type vide a beaucoup d'utilités.
    Je n'en doute pas mais je suis curieux de savoir lesquelles.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  9. #9
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Un exemple a été cité plus haut, les allocateurs.
    Il y aussi le policy-based design, la méta-programmation, les tags d'identification, etc.
    Boost ftw

  10. #10
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Un example a été cité plus haut, les allocateurs.
    Il y aussi le policy-based design, la méta-programmation, les tags d'identification, etc.
    Pour les allocateurs, je ne vois pas. Je ne maîtrise sans doute pas assez le sujet. Si au passage tu as de la doc dessus, je suis preneur

    Les autres me parlent, mais je n'y avait pas pensés naturellement.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  11. #11
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Points : 588
    Points
    588
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    Pour les allocateurs, je ne vois pas. Je ne maîtrise sans doute pas assez le sujet. Si au passage tu as de la doc dessus, je suis preneur

    Les autres me parlent, mais je n'y avait pas pensés naturellement.
    Imagine un objet de type rien_du_tout.

    Tu as un objet, et un objet veut dire de la mémoire allouée, or, pour allouer de la mémoire, il faut une taille d'allocation. Si tu as une taille de 0, tu n'as pas d'allocation (on alloue pas "rien" :p). Or il faut pouvoir retrouver cette variable, donc elle doit avoir une adresse où elle est stockée en mémoire. Pour avoir une adresse, la variable doit être allouée, pour être allouée, elle doit avoir une taille supérieure à 0.

    Maintenant, imagine 2 objets de type rien_du_tout.
    Si on avait des tailles 0 et donc pas d'allocation, il serait strictement impossible de distinguer ces 2 objets, car en réalité, elles n'existeraient pas réellement.

    Pour qu'elles existent, il leur faut une taille d'allocation, d'où le minimum 1.

  12. #12
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Citation Envoyé par JulienDuSud Voir le message
    Imagine un objet de type rien_du_tout.

    Tu as un objet, et un objet veut dire de la mémoire allouée, or, pour allouer de la mémoire, il faut une taille d'allocation. Si tu as une taille de 0, tu n'as pas d'allocation (on alloue pas "rien" :p). Or il faut pouvoir retrouver cette variable, donc elle doit avoir une adresse où elle est stockée en mémoire. Pour avoir une adresse, la variable doit être allouée, pour être allouée, elle doit avoir une taille supérieure à 0.

    Maintenant, imagine 2 objets de type rien_du_tout.
    Si on avait des tailles 0 et donc pas d'allocation, il serait strictement impossible de distinguer ces 2 objets, car en réalité, elles n'existeraient pas réellement.

    Pour qu'elles existent, il leur faut une taille d'allocation, d'où le minimum 1.
    Nan, ca ok, j'avais compris mais merci de l'explication mais je suis pas sûr que ca soit ce que loufoque voulait dire ou alors j'ai compris de travers sa phrase.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  13. #13
    Membre régulier Avatar de Midou45
    Homme Profil pro
    Ingénieur
    Inscrit en
    Novembre 2007
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Algérie

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Novembre 2007
    Messages : 156
    Points : 110
    Points
    110
    Par défaut
    waw sa me rappel s cours de philo ..
    Je trouve que c'est logique qu'un objet vide à une taille > 0 , pour la raison d'allocation, mais en tant que débutant en programmation je n'arrive pas à assimiler l'utilité de ces objets vides, je pense qu'ils sont utiles vu cette discussion et la participation des gens.. mais pour moi c'est flou ..
    " La nature nous a donné deux oreilles et seulement une langue afin de pouvoir écouter d'avantage et parler moins." Zénon d'Elée

  14. #14
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Bah std::allocator<T> est un type vide.
    Boost ftw

  15. #15
    Membre éclairé

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Points : 858
    Points
    858
    Par défaut
    Il me semble pas que la norme impose que std::allocator<T> soit un type vide.

    Et là est justement l'intérêt d'avoir sizeof(T) > 0 quelque soit le type T, même vide, c'est que les propriétés fondamentales des objets (identité, occupation mémoire, ...) ne dépendent pas du fait qu'ils soient vides ou pas. Et vis-à-vis des templates, notamment, c'est important.

  16. #16
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Citation Envoyé par JulienDuSud Voir le message
    Imagine un objet de type rien_du_tout.

    Tu as un objet, et un objet veut dire de la mémoire allouée, or, pour allouer de la mémoire, il faut une taille d'allocation...
    Pas d'accord. C'est une vue matérialiste. Un objet c'est d'abord une âme, et ensuite éventuellement un corps

    Sérieusement, un objet vide n'a pas besoin de mémoire. Ce n'est conceptuellement pas nécessaire. La preuve, elle ne sera jamais utilisée. Sinon, prouvez-moi qu'un programme compilé va y mettre quelque chose d'utile.

    La décision des concepteurs du C++ d'allouer de la mémoire est pratique, sans doute pour simplifier un chouia l'écriture du compilateur. Mais je pense que ce n'était pas fondamentalement nécessaire.

    Je ne vois aucun cas pratique et concret où il serait utile de connaître l'adresse en mémoire d'un objet vide afin, éventuellement, de le distinguer d'une autre.
    Je repose la question: le faites-vous ?
    Si on décidait du jour au lendemain de faire en sorte que les compilos gèrent sizeof(rien_du_tout)==0, faudrait-il revoir et vérifier tous les programmes du monde ?

  17. #17
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Citation Envoyé par Sylvain Togni Voir le message
    Il me semble pas que la norme impose que std::allocator<T> soit un type vide.

    Et là est justement l'intérêt d'avoir sizeof(T) > 0 quelque soit le type T, même vide, c'est que les propriétés fondamentales des objets (identité, occupation mémoire, ...) ne dépendent pas du fait qu'ils soient vides ou pas. Et vis-à-vis des templates, notamment, c'est important.
    std::allocator<T> est toujours vide, quelque soit T.
    Ce n'est pas imposé, c'est un constat dans les implémentations actuelles (au moins sous Visual).

  18. #18
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Points : 588
    Points
    588
    Par défaut
    Citation Envoyé par camboui Voir le message
    Pas d'accord. C'est une vue matérialiste. Un objet c'est d'abord une âme, et ensuite éventuellement un corps

    Sérieusement, un objet vide n'a pas besoin de mémoire. Ce n'est conceptuellement pas nécessaire. La preuve, elle ne sera jamais utilisée. Sinon, prouvez-moi qu'un programme compilé va y mettre quelque chose d'utile.

    La décision des concepteurs du C++ d'allouer de la mémoire est pratique, sans doute pour simplifier un chouia l'écriture du compilateur. Mais je pense que ce n'était pas fondamentalement nécessaire.

    Je ne vois aucun cas pratique et concret où il serait utile de connaître l'adresse en mémoire d'un objet vide afin, éventuellement, de le distinguer d'une autre.
    Je repose la question: le faites-vous ?
    Si on décidait du jour au lendemain de faire en sorte que les compilos gèrent sizeof(rien_du_tout)==0, faudrait-il revoir et vérifier tous les programmes du monde ?
    La gestion des identités des objet se joue beaucoup plus bas, au niveau CPU et pas au niveau du pré-processeur. Or, pour que le CPU ait connaissance de tes objets, il faut qu'ils existent et qu'il puisse les distinguer les uns des autres, d'où la nécéssite de lui allouer de la mémoire.

    Aussi, un type vide reste un type, deux variables dont le type serait différents et qui ne contiendrait pas de données restent 2 types distinctes,

  19. #19
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Aussi, un type vide reste un type, deux variables dont le type serait différents et qui ne contiendrait pas de données restent 2 types distinctes,
    Du point de vue du langage, oui mais conceptuellement, est ce que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    class A{};
    class B{};
    sont différentes l'une de l'autre ?

    Je ne pense pas, de là à dire qu'il devrait y avoir une substituabilité entre les deux, il n'y a plus qu'un pas à faire.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  20. #20
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Citation Envoyé par JulienDuSud Voir le message
    La gestion des identités des objet se joue beaucoup plus bas, au niveau CPU et pas au niveau du pré-processeur. Or, pour que le CPU ait connaissance de tes objets, il faut qu'ils existent et qu'il puisse les distinguer les uns des autres, d'où la nécéssite de lui allouer de la mémoire.

    Aussi, un type vide reste un type, deux variables dont le type serait différents et qui ne contiendrait pas de données restent 2 types distinctes,
    ??
    Tu veux bien répondre à la question et me dire en quoi le CPU a besoin de connaitre et réserver une zone de mémoire dont il ne fera jamais rien ?

Discussions similaires

  1. sizeof() d'une structure
    Par tut dans le forum MFC
    Réponses: 12
    Dernier message: 29/08/2006, 18h21
  2. utilisation de sizeof
    Par Mokhtar BEN MESSAOUD dans le forum C
    Réponses: 13
    Dernier message: 02/12/2005, 18h16
  3. Sizeof d'un pointeur sur char ...
    Par Mike888 dans le forum C
    Réponses: 8
    Dernier message: 03/11/2005, 13h04
  4. sizeof
    Par drKzs dans le forum C
    Réponses: 6
    Dernier message: 04/10/2003, 23h48
  5. Erreurs (sizeof)
    Par deepfear dans le forum C
    Réponses: 13
    Dernier message: 25/09/2003, 13h56

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