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

C++ Discussion :

sizeof() et preprocesseur


Sujet :

C++

  1. #21
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Boost "triche".
    Effectivement, pour visual par expl, il utilise le support du compilo pour les traits (__is_pod en l'occurrence). Et là, plus de méta prog, c'est du dur !

  2. #22
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Citation Envoyé par camboui Voir le message
    Au delà du sizeof(), quelles autres astuces peut-on utiliser en métaprogramation ?
    Tiens d'ailleurs, à propos de méta-programmation, cela faisait des années que je n'avais jamais rien bitté à la métaprog avant de soudainement recevoir une révélation cosmique grâce à cet article :

    What Does Haskell Have to Do with C++?

    Pourquoi personne n'avait jamais fait d'article aussi clair et simple avant ?

  3. #23
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Citation Envoyé par Arzar Voir le message
    Tiens d'ailleurs, à propos de méta-programmation, cela faisait des années que je n'avais jamais rien bitté à la métaprog avant de soudainement recevoir une révélation cosmique grâce à cet article :

    What Does Haskell Have to Do with C++?

    Pourquoi personne n'avait jamais fait d'article aussi clair et simple avant ?

    Hum, dans MC++D alexandreiscu fait clairement le paralléle. Et perso c'est d'avoir fait de la metaprog en C++ qui m'a permis d'aborder plus facilement haskell (oui je fais les choses à l'envers :p).

  4. #24
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    oufti

    Eh bien merci les gars.
    Je connaissais un peu les boost::call_traits, voilà que je vais pouvoir affronter les type_traits désormais

    Mais, c'est quoi POD ? J'ai cru comprendre que c'est une structure "minimaliste", i.e. dont les membres sont eux-mêmes POD ou primitifs et dont les méthodes éventuelles sont non virtuelles, et pas de constructeur ni de destructeur explicites.

  5. #25
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    POD pour plain' old data, ça veut dire comme tu l'as dis que c'est soit un type primitifs soit une structure composé uniquement de type eux mêmes pod. les structs au sens C, les primitifs etc.

  6. #26
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par camboui Voir le message
    Mais, c'est quoi POD ?
    Citation Envoyé par The norme
    Arithmetic types (3.9.1), enumeration types, pointer types, and pointer to member types (3.9.2), and cvqualified versions of these types (3.9.3) are collectively called scalar types. Scalar types, POD-struct types, POD-union types (clause 9), arrays of such types and cv-qualified versions of these types (3.9.3) are collectively called POD types
    et :
    Citation Envoyé par The norme
    A POD-struct is an aggregate class that has no non-static data members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no user-defined copy assignment operator and no user-defined destructor. Similarly, a POD-union is an aggregate union that has no non-static data members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no userdefined copy assignment operator and no user-defined destructor. A POD class is a class that is either a POD-struct or a POD-union.
    [EDIT] grilled
    Je rajoute juste qu'un type POD peut avoir des fonctions membres mais pas d'opérateur= ou de destructeur défini (ni de fonctions virtuelles bien sûr). La chose que j'oublie tout le temps est est-ce qu'une structure qui dérive d'une structure POD tout en respectant les critères est elle-même POD ? J'aurais tendance à dire non.

  7. #27
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    std::string n'est pas POD alors. Et toute structure contenant des std::string ne l'est pas non plus.
    Comme tu dis les PODs sont donc des struct "C like".
    Je me demande dans quel cas ça peut-être utile ce genre d'info.

  8. #28
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Citation Envoyé par camboui Voir le message
    std::string n'est pas POD alors. Et toute structure contenant des std::string ne l'est pas non plus.
    Comme tu dis les PODs sont donc des struct "C like".
    Je me demande dans quel cas ça peut-être utile ce genre d'info.
    Tu peux faire des memset() sur des POD... fais un memset() sur une string tu vas rigoler :p.


    edit s/memcpy()/memset()

  9. #29
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    L'inconvénient est la notion de "constructeur trivial": Ceci n'est pas considéré comme trivial:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct st_testPod2
    {
    	int titi;
     
    	explicit st_testPod2() : titi() {}
    	explicit st_testPod2(int titi) : titi(titi) {}
    };
    Donc, on ne peut pas utiliser le raccourci return st_testPod2(42); si on veut que la structure soit POD (mais bon, on peut facilement faire une fonctionpour ça).
    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.

  10. #30
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Citation Envoyé par Envoyé par The norme
    A POD-struct is an aggregate class that has no non-static data members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no user-defined copy assignment operator and no user-defined destructor. Similarly, a POD-union is an aggregate union that has no non-static data members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no userdefined copy assignment operator and no user-defined destructor. A POD class is a class that is either a POD-struct or a POD-union.
    Merci.
    Mais c'est le genre de prose qui dépasse mes capacités intellectuelles. J'ai beau lire 10 fois, ça reste incompréhensible pour moi
    C'est là qu'on se dit qu'une image ou (un exemple) et son contraire valent 1000 mots

  11. #31
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Citation Envoyé par Goten Voir le message
    Tu peux faire des memset() sur des POD... fais un memcpy sur une string tu vas rigoler :p.


    edit s/memcpy()/memset()
    Là je comprends mieux. Une POD est une structure dont l'operateur d'assignation et le copy constructeur attribués par le compilo font l'équivalent d'un memcpy.

  12. #32
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Citation Envoyé par camboui Voir le message
    std::string n'est pas POD alors. Et toute structure contenant des std::string ne l'est pas non plus.
    Comme tu dis les PODs sont donc des struct "C like".
    Je me demande dans quel cas ça peut-être utile ce genre d'info.
    Par exemple dans la STL de VS ou celle de GCC un appel à std::copy peut être optimisé en memove si le type pointé par l'itérateur est un pod.

    Le code de la STL de gcc est relativement facile à suivre (comparé à celui de visual )

    std::copy appelle tout d'abord __copy_move_a() qui va déterminer si le type est un pod ou non :
    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
     
    template<bool _IsMove, typename _II, typename _OI>
    inline _OI
    __copy_move_a(_II __first, _II __last, _OI __result)
    {
       typedef typename iterator_traits<_II>::value_type _ValueTypeI;
       typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
       typedef typename iterator_traits<_II>::iterator_category _Category;
       const bool __simple = (__is_pod(_ValueTypeI)
                              && __is_pointer<_II>::__value
                              && __is_pointer<_OI>::__value
                              && __are_same<_ValueTypeI, _ValueTypeO>::__value);
     
     return std::__copy_move<_IsMove, __simple,
                             _Category>::__copy_m(__first, __last, __result);
    }
    Si non, alors __simple == false, et on tombe au final sur une boucle for :
    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
    18
     
    template<>
    struct __copy_move<false, false, random_access_iterator_tag>
    {
       template<typename _II, typename _OI>
       static _OI
       __copy_m(_II __first, _II __last, _OI __result)
       { 
          typedef typename iterator_traits<_II>::difference_type _Distance;
          for(_Distance __n = __last - __first; __n > 0; --__n)
          {
              *__result = *__first;
              ++__first;
              ++__result;
          }
        return __result;
       }
    };
    Par contre si __simple = true, c'est un memmove :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    template<bool _IsMove>
    struct __copy_move<_IsMove, true, random_access_iterator_tag>
    {
      template<typename _Tp>
      static _Tp*
      __copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result)
      {
         __builtin_memmove(__result, __first,
                          sizeof(_Tp) * (__last - __first));
           return __result + (__last - __first);
      }
     ;

  13. #33
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Joli !

    Au fait, pour savoir si un type est primitif, suffit-il d'utiliser __is_class() ? (et donc ==false)

    EDIT: je me répond: pas tout à fait. Les références et pointeurs répondent aussi "false" à la question.

  14. #34
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par camboui Voir le message
    Joli !

    Au fait, pour savoir si un type est primitif, suffit-il d'utiliser __is_class() ? (et donc ==false)

    EDIT: je me répond: pas tout à fait. Les références et pointeurs répondent aussi "false" à la question.
    Arzar montrait l'exemple d'implémentation de GCC pour montrer l'utilité de ce genre d'info. Le code est donc le code de l'implémentation de la STL utilisée par GCC. A ce titre __is_class n'est pas standard et dépend du compilateur (ici, GCC).
    Il faut attendre C++0x pour avoir des classes traits standards et en particulier un std::is_class.

  15. #35
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Arzar montrait l'exemple d'implémentation de GCC pour montrer l'utilité de ce genre d'info. Le code est donc le code de l'implémentation de la STL utilisée par GCC. A ce titre __is_class n'est pas standard et dépend du compilateur (ici, GCC).
    Il faut attendre C++0x pour avoir des classes traits standards et en particulier un std::is_class.
    On peut d'ailleurs attirer l'attention de tous sur le fait que, de manière générale, tout ce qui est préfixé par __ est propre à l'implémentation faite par les développeurs et n'est donc, par définition, ni standard ni garanti avec d'autres implémentations, que ce soit du point de vue du fournisseur ou du point de vue de la version...
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  16. #36
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    OK, bien compris.
    A partir du moment où autant GCC que MSVC supporte "ces petits machins" (__is_pod, __is_class), il n'y a pas trop de soucis à se faire. Il sera toujours temps de faire un "find and replace" dans l'ensemble du code pour les remplacer par leur équivalent std:: (il ne devrait pas y en avoir beaucoup...)

  17. #37
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par camboui Voir le message
    OK, bien compris.
    A partir du moment où autant GCC que MSVC supporte "ces petits machins" (__is_pod, __is_class), il n'y a pas trop de soucis à se faire.
    A conditions qu'ils aient le même sens pour les deux compilateurs...
    Et ton code ne sera pas portable avec d'autres compilateurs.
    Et pis, un jour il peuvent même disparaitre ou être renommé dans une nouvelle version de ces compilateurs. Bref beaucoup de contrainte et de maintenance que Boost.Trait t'épargne en attendant C++0x

  18. #38
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Comme on essaye de le faire valoir:
    • Il n'y a pas que VC++ et Gcc (il y a les compilateurs intel, comeau et d'autres encore)
    • ils peuvent exister dans la version 2.3 mais disparaitre dans la version 3 (voire, dans la version 2.4) et ne pas exister dans la version 1.9
    • ...
    Selon les besoins de ton projet, cela peut apporter pas mal de contraintes à la "portabilité"
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  19. #39
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    J'ai cru comprendre que std::is_class et std::is_pod seront standards. Vous ai-je mal compris ?

  20. #40
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par camboui Voir le message
    J'ai cru comprendre que std::is_class et std::is_pod seront standards. Vous ai-je mal compris ?
    Ils le seront... en C++0x...

    En attendant, les utiliser (surtout si, pour ce faire, tu dois utiliser une version préfixée par __) n'a rien de certain...

    Nous sommes tous en attente de l'une ou l'autre possibilité offerte par C++0x
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 3 PremièrePremière 123 DernièreDernière

Discussions similaires

  1. sizeof() d'une structure
    Par tut dans le forum MFC
    Réponses: 12
    Dernier message: 29/08/2006, 18h21
  2. Sizeof d'un pointeur sur char ...
    Par Mike888 dans le forum C
    Réponses: 8
    Dernier message: 03/11/2005, 13h04
  3. [PREPROCESSEUR] quelle difference ??
    Par chronos dans le forum C++
    Réponses: 11
    Dernier message: 05/05/2005, 19h15
  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