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 :

Surcharge et types entiers : laquelle devrait être choisie ?


Sujet :

Langage C++

  1. #1
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut Surcharge et types entiers : laquelle devrait être choisie ?
    Bonjour à tous,

    J'ouvre ce sujet à la suite de cette discussion et il ne traitera pas spécifiquement des enums :
    http://www.developpez.net/forums/d13...tout-a-fait-x/

    L'objectif de cette discussion n'est pas de savoir ce que dit la norme ni de ce que font actuellement les différents compilateurs, mais de savoir ce que vous trouvez logique comme comportements et pourquoi.

    Je vous proposes un code relativement simple contenant 6 appels à 3 fonctions surchargés :
    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    #include<iostream>
     
     
    enum : short { val_short };
    enum : int   { val_int   };
     
     
    void short_or_int(short)
    { std::cout << "short"; }
     
    void short_or_int(int)
    { std::cout << "int"; }
     
     
    void int_or_long(int)
    { std::cout << "int"; }
     
    void int_or_long(long)
    { std::cout << "long"; }
     
     
    void long_or_longlong(long)
    { std::cout << "long"; }
     
    void long_or_longlong(long long)
    { std::cout << "longlong"; }
     
     
    int main()
    { 
        short var_short(0);
        int   var_int  (0);
     
        std::cout << "short_or_int     with var_short : "; short_or_int(var_short)  ; std::cout << std::endl;
        std::cout << "int_or_long      with var_short : "; int_or_long(var_short)   ; std::cout << std::endl;
        std::cout << "long_or_longlong with var_int   : "; long_or_longlong(var_int); std::cout << std::endl;
     
     
        std::cout << "short_or_int     with val_short : "; short_or_int(val_short)  ; std::cout << std::endl;
        std::cout << "int_or_long      with val_short : "; int_or_long(val_short)   ; std::cout << std::endl;
        std::cout << "int              with val_int   : "; long_or_longlong(val_int); std::cout << std::endl;
    }
    La question est de savoir ce que vous, développeur, attendez de ces appels de manière logique. Les réponses possibles sont :
    • L'appel ne doit pas compiler car aucune fonction ne correspond aux arguments.
    • L'appel ne doit pas compiler car il y a ambiguïté, plusieurs surcharges correspondent et aucune n'est à privilégier.
    • L'appel est valide car une seule surcharge correspond aux arguments.
    • L'appel est valide car plusieurs surcharges correspondent aux arguments mais une seule est à privilégier.

    L'objectif n'est pas de déterminer ce qu'il doit se passer en réalité, seulement de discuter de ce qui doit se passer de la manière la plus logique qui soit.

    Les trois premiers appels ne font pas usage des notions d'énumérations avec type sous-jacent explicitent du C++11, ils sont plus classiques mais cependant pas nécessairement dénués d'intérêt. Les trois derniers appels utilisent ces énumérations ce qui peut introduire des raisonnements différents.

    Je rappel juste deux choses :
    • Les types entiers ont en C++ un certain "ordre" entre eux, ce n'est pas nécessaire de rentrer dans les détails ici, il est juste à noter que short < int < long < long long, où < désigne cet ordre.
    • Les énumérations définissent un nouveau type, ainsi le type de val_short et val_int n'est ni short ni int, c'est autre chose (le type est non nommé ici). Le type sous-jacent (respectivement short et int) est le type des valeurs de l'énumération à l'intérieur de celle-ci, à l'extérieur ils ont le type définit par l'énumération.


    Bien entendu il sera intéressant dans la suite de la discussion de s'interroger sur ce qu'il doit se passer selon la norme et de le confronter aux premières intuitions.

  2. #2
    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
    Salut,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    short_or_int(var_short)
    devrait sortir "short", sans l'ombre d'un doute (c'est l'expression qui matche parfaitement)
    pourrait tout aussi bien sortir int que long, et ce, pour différente raisons:
    on rencontre beaucoup d'architectures sur lesquelles sizeof(long) == sizeof(int) (ce qui est parfaitement autorisé par la norme )
    si différence de taille il y a, le compilateur devrait choisir le type qui permet, pour l'architecture, de travailler le plus facilement.

    Par contre, il choisira souvent de travailler avec un int

    Je ne serais donc pas surpris de voir "int" en sortie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long_or_longlong(var_int);
    sensiblement la meme chose que juste avant, bien que sizeof(long) et sizeof(long long) ne soient généralement pas égaux...

    Je dirais : selon l'architecture : long en 32 bits, long long en 64 car ce sont "typiquement" les tailles qui s'adaptent le mieux aux différents accumulateurs

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    short_or_int(val_short)
    Je dirais short, c'est ce qui "matche" le mieux
    aussi bien int que long, avec une préférence pour int, pour les mêmes raisons que plus haut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long_or_longlong(val_int);
    Encore une fois, cela dépendra de l'architecture...
    long en 32 bits, long long en 64 bits, pour les même raisons que plus haut
    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

  3. #3
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Salut,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    short_or_int(var_short)
    devrait sortir "short", sans l'ombre d'un doute (c'est l'expression qui matche parfaitement)
    Pour celui-ci je suis totalement d'accord.

    Citation Envoyé par koala01 Voir le message
    pourrait tout aussi bien sortir int que long, et ce, pour différente raisons:
    on rencontre beaucoup d'architectures sur lesquelles sizeof(long) == sizeof(int) (ce qui est parfaitement autorisé par la norme )
    si différence de taille il y a, le compilateur devrait choisir le type qui permet, pour l'architecture, de travailler le plus facilement.
    La réponse se trouve dans la norme (et à moins que je l'ai mal interprété je connais normalement les comportements attendus) mais je préfère exclure la norme de la discussion le plus possible pour le moment (l'objectif de la discussion est justement de voir si ces règles sont logiques ou non).

    Pour toi c'est donc un UB (enfin implementation-defined) : le compilateur a différentes possibilités alors il est "libre" de prendre celle qu'il veut (ou plus exactement de suivre l'architecture) ? Ce raisonnement me gène un peu dans le sens où l'algo de sélection des surcharges se doit d'être robuste parce qu’il le peut : le typage du C++ fait qu'il a bien assez d'information à la compilation pour dire si il peut ou non choisir une surcharge et ne pas jouer aux "dès".

    Citation Envoyé par koala01 Voir le message
    Je ne serais donc pas surpris de voir "int" en sortie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long_or_longlong(var_int);
    sensiblement la meme chose que juste avant, bien que sizeof(long) et sizeof(long long) ne soient généralement pas égaux...
    Le fait que tu arrives à la même conclusion me rassure, donc pour toi il est donc bien logique que le triplet short/int/long et int/long/long long se comporte de la même manière ? Sur ce point je suis assez d'accord.

    Citation Envoyé par koala01 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    short_or_int(val_short)
    Je dirais short, c'est ce qui "matche" le mieux
    Donc pour toi la conversion du type de l'enum vers le type sous-jacent de l'enum devrait être prioritaire devant tout les autres (excepté du type de l'enum vers le type de l'enum) ? Je trouve ceci logique aussi.

  4. #4
    Membre Expert

    Avatar de germinolegrand
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2010
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Par défaut
    Pour ma part, qu'importe le détail, je m'attendrais en tout premier lieu à ce que les 3 résultats du bas soient strictement identiques aux 3 résultats du haut au minimum. Sinon l'intérêt de définir un type sous-jacent aux enums faiblement typées est grandement diminué.

    En effet, les enums faiblement typées ont pour intérêt majeur en C++11 de pouvoir être "confondues" avec leur type sous-jacent, les valeurs servant avant tout d'étiquettes facilitant l'écriture du code (et la généricité bien entendu).

    Pour les enums fortement typées, la question se pose moins puisqu'il faut de toute façon faire un cast explicite.

  5. #5
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Citation Envoyé par germinolegrand Voir le message
    Pour ma part, qu'importe le détail, je m'attendrais en tout premier lieu à ce que les 3 résultats du bas soient strictement identiques aux 3 résultats du haut au minimum. Sinon l'intérêt de définir un type sous-jacent aux enums faiblement typées est grandement diminué.
    Bien que les énumérations définissent dans tout les cas un nouveaux types, je peux comprendre cette idée : au sein de l'énumération le type des éléments est le type sous-jacent, donc en cas de conversion la priorité est laissé au type sous-jacent. C'est aussi quelque-chose que Koala01 trouverait naturel si j'ai bien compris ses propos.

  6. #6
    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 Flob90 Voir le message
    La réponse se trouve dans la norme (et à moins que je l'ai mal interprété je connais normalement les comportements attendus) mais je préfère exclure la norme de la discussion le plus possible pour le moment (l'objectif de la discussion est justement de voir si ces règles sont logiques ou non).
    Ma référence à la norme avait juste pour but de rappeler que sizof(int) == sizeof(long) est parfaitement légal
    Pour toi c'est donc un UB (enfin implementation-defined) : le compilateur a différentes possibilités alors il est "libre" de prendre celle qu'il veut (ou plus exactement de suivre l'architecture) ? Ce raisonnement me gène un peu dans le sens où l'algo de sélection des surcharges se doit d'être robuste parce qu’il le peut : le typage du C++ fait qu'il a bien assez d'information à la compilation pour dire si il peut ou non choisir une surcharge et ne pas jouer aux "dès".
    Hummm... oui, et non...

    je comprends parfaitement ce qui te gène, mais je placerais plutôt ce genre de comportement dans la partie "implementation dependant".

    si c'est un "coup de dés", ils sont fortement pipés
    Donc pour toi la conversion du type de l'enum vers le type sous-jacent de l'enum devrait être prioritaire devant tout les autres (excepté du type de l'enum vers le type de l'enum) ? Je trouve ceci logique aussi.
    Cela me paraitrait effectivement logique
    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

  7. #7
    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 Flob90 Voir le message
    Bien que les énumérations définissent dans tout les cas un nouveaux types, je peux comprendre cette idée : au sein de l'énumération le type des éléments est le type sous-jacent, donc en cas de conversion la priorité est laissé au type sous-jacent. C'est aussi quelque-chose que Koala01 trouverait naturel si j'ai bien compris ses propos.
    Ah oui, bien sur!

    Si on a quelque chose qui "matche" parfaitement, on l'utilise, sinon, on prend ce qui "demande le moindre effort".

    Pour ma part, je considère que ce qui demande "le moindre effort" consiste à promouvoir dans le type le plus adapté au processeur et est donc dépendant de la plateforme/ de l'architecture

    Enfin, si on ne dispose pas de la surcharge qui permet d'utiliser le type le plus adapté à l'architecture, le "moindre effort" consiste à promouvoir la valeur énumérée au rang d'entier (sous réserve toute fois que le type sous-jacent de la valeur énumérée soit "suffisamment petit" pour pouvoir être promu en entier )
    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

  8. #8
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Ma référence à la norme avait juste pour but de rappeler que sizof(int) == sizeof(long) est parfaitement légal
    Oui, c'est vrai aussi .

    Citation Envoyé par koala01 Voir le message
    Hummm... oui, et non...

    je comprends parfaitement ce qui te gène, mais je placerais plutôt ce genre de comportement dans la partie "implementation dependant".
    Je comprend pas ce que tu veux dire, mais ca me gène toujours, les dès ont beau être pipé, si je compile le même programme sur deux machines j'ai potentiellement deux comportements totalement différent (ça dépend ce que font les surcharges). Et ceci me gène en effet.

  9. #9
    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 Flob90 Voir le message
    Je comprend pas ce que tu veux dire, mais ca me gène toujours, les dès ont beau être pipé, si je compile le même programme sur deux machines j'ai potentiellement deux comportements totalement différent (ça dépend ce que font les surcharges). Et ceci me gène en effet.
    Là aussi, je te comprends...

    Mais, sans faire référence à la norme pour le problème qui nous intéresse, je ne peux que constater qu'elle contient tant de comportements dépendants de l'implémentation que cela ne me gênerait pas outre mesure si c'en était un de plus
    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

  10. #10
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Ah oui, bien sur!

    Si on a quelque chose qui "matche" parfaitement, on l'utilise, sinon, on prend ce qui "demande le moindre effort".
    Je suis totalement d'accord, et de manière global c'est bien l'esprit dans lequel se passe l'algo de sélection des surcharges (au sens large, pas juste avec mon exemple).

    Citation Envoyé par koala01 Voir le message
    Pour ma part, je considère que ce qui demande "le moindre effort" consiste à promouvoir dans le type le plus adapté au processeur et est donc dépendant de la plateforme/ de l'architecture
    Cette partie me gène vraiment même si je comprends bien ton idée. Cependant, le type int est par définition le type le mieux adapté à l'architecture (c'est normatif). Tu serais donc pour dire que si il n'y a pas correspondance exact alors la conversion prioritaire est vers int ?

    Citation Envoyé par koala01 Voir le message
    Enfin, si on ne dispose pas de la surcharge qui permet d'utiliser le type le plus adapté à l'architecture, le "moindre effort" consiste à promouvoir la valeur énumérée au rang d'entier (sous réserve toute fois que le type sous-jacent de la valeur énumérée soit "suffisamment petit" pour pouvoir être promu en entier )
    Si tu entends entier au sens int, alors c'est redondant, promouvoir en int c'est aussi promouvoir vers le type le plus adapté à l'architecture.

    Donc si je te suis bien (c'est pas garanti avec les posts croisés ), la logique serait, par ordre de priorité :
    • correspondance exacte
    • int : le type le plus adapté à l'architecture
    • autre ? dans un autre particulier ? tous au même niveau ?

    Et dans le cas des enums avec type sous-jacent explicite, tu mets la conversion énumération vers type sous-jacent à quel niveau ? Avant int ? Après int ? Au même niveau que int ?

  11. #11
    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 Flob90 Voir le message
    Cette partie me gène vraiment même si je comprends bien ton idée. Cependant, le type int est par définition le type le mieux adapté à l'architecture (c'est normatif).
    Ouppss.. j'avais oublié ce point
    Tu serais donc pour dire que si il n'y a pas correspondance exact alors la conversion prioritaire est vers int ?
    Si c'est normatif, oui
    Si tu entends entier au sens int, alors c'est redondant, promouvoir en int c'est aussi promouvoir vers le type le plus adapté à l'architecture.
    Au début, j'entendais effectivement entier au sens de int, mais pour éviter la confusion des genres, je dirai (en ayant cette fois en tete que le type int est prioritaire):
    S'il n'y a pas de surcharge en int, alors, promotion "la plus petite possible" de la valeur (AKA : préférer promouvoir en long plutot qu'en long long)
    Donc si je te suis bien (c'est pas garanti avec les posts croisés ), la logique serait, par ordre de priorité :
    • correspondance exacte
    • int : le type le plus adapté à l'architecture
    oui, dans cet ordre, et en troisième lieu promotion dans le type le plus petit possible pour lequel il existe une surcharge
    Et dans le cas des enums avec type sous-jacent explicite, tu mets la conversion énumération vers type sous-jacent à quel niveau ? Avant int ? Après int ? Au même niveau que int ?
    je met la conversion dans le type sous-jacent en priorité, si correspondance exacte.
    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

  12. #12
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Pour les int (ca m'évitera de rechercher le passage plus tard) :
    Plain ints have the natural size suggested by the
    architecture of the execution environment44;
    (3.9.1 §2)

    Donc en reprenant tes derniers messages pour toi on aurait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    short_or_int(var_short)   ; //short
    int_or_long(var_short)    ; //int
    long_or_longlong(var_int); //long
    short_or_int(val_short)   ; //short
    int_or_long(val_short)    ; //int
    long_or_longlong(val_int); //long
    C'est une logique qui se tient je trouve, c'est probablement pas la seule.

  13. #13
    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 Flob90 Voir le message
    Pour les int (ca m'évitera de rechercher le passage plus tard) :

    (3.9.1 §2)

    Donc en reprenant tes derniers messages pour toi on aurait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    short_or_int(var_short)   ; //short
    int_or_long(var_short)    ; //int
    long_or_longlong(var_int); //long
    short_or_int(val_short)   ; //short
    int_or_long(val_short)    ; //int
    long_or_longlong(val_int); //long
    C'est une logique qui se tient je trouve, c'est probablement pas la seule.
    oui, c'est bien ce qui me semble le plus logique.

    Comme tu dis, d'autres pourraient avoir une logique différente, et je serais d'ailleurs content de m'y frotter
    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

  14. #14
    Membre Expert

    Avatar de germinolegrand
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2010
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Par défaut
    Pour ma part, ce serait plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    short_or_int(var_short)   ; //short
    int_or_long(var_short)    ; //int with a warning
    long_or_longlong(var_int); //long with a warning
    short_or_int(val_short)   ; //short
    int_or_long(val_short)    ; //int with a warning
    long_or_longlong(val_int); //long with a warning
    Comme dit plus haut, le cas du short me paraît clair.
    La conversion vers int me parait légale (pas spécialement claire), on voit régulièrement des char promus en int dans la SL, ce n'est pas extravagant.
    La conversion vers long me paraît par contre risquée, ce type n'étant pas fixé. Toutefois pour des raisons de cohérence la règle "promu vers le plus proche vers le haut" me semble légitime. La conversion vers longlong me parait elle improbable, pour quelle raison le C++ choisirait-il de prendre une solution qui prend d'avantage de place en mémoire, ce serait une nouveauté.

    Toutefois, j'ai vu à quel point les conversions implicites qui ne perdent pas de données peuvent être dangereuses (parce que si vous sérialisez, ça veut aussi dire qu'il faudra désérialiser quelque part, et là c'est le drame ma bonne dame), aussi bien que je préfère avoir un comportement défini plutôt qu'une ambiguïté qui empêche carrément de compiler, je demande plutôt un bon vieux warning.

  15. #15
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Citation Envoyé par germinolegrand Voir le message
    Pour ma part, ce serait plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    short_or_int(var_short)   ; //short
    int_or_long(var_short)    ; //int with a warning
    long_or_longlong(var_int); //long with a warning
    short_or_int(val_short)   ; //short
    int_or_long(val_short)    ; //int with a warning
    long_or_longlong(val_int); //long with a warning
    Je verrais ça aussi, les enums typés qui font des appels ambigus c'est bizarre, et en tout cas pas intuitif.

  16. #16
    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 Iradrille Voir le message
    Citation Envoyé par germinolegrand Voir le message
    Pour ma part, ce serait plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    short_or_int(var_short)   ; //short
    int_or_long(var_short)    ; //int with a warning
    long_or_longlong(var_int); //long with a warning
    short_or_int(val_short)   ; //short
    int_or_long(val_short)    ; //int with a warning
    long_or_longlong(val_int); //long with a warning
    Je verrais ça aussi, les enums typés qui font des appels ambigus c'est bizarre, et en tout cas pas intuitif.
    Je vous l'accorde (à tous les deux).

    Cependant, il n'y a pas vraiment de raison d'avoir un avertissement sur ce coup là, car la promotion se fait toujours du type dont la taille est la plus petite vers le type dont la taille est la plus grande, et que la promotion est implicite dés le moment où il n'y a pas d'autre correspondance.

    Il ne faut à mon sens(et encore, c'est à voir avec l'équipe de développement du compilateur ) un avertissement que lorsqu'une conversion peut poser un problème (de perte de données, ou de valeur mal évaluée, par exemple): lorsque l'on converti une variable non signée en une variable de même type signée (ou vice versa) ou lorsque le type de la variable "d'origine" est "potentiellement plus grand(*)" que le type de la variable de destination (en cas de conversion toujours )

    (*) (pour rappel, la relation entre deux types primitifs est toujours définie comme "plus petite ou égale :d ")
    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

  17. #17
    Membre Expert

    Avatar de germinolegrand
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2010
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Par défaut
    Cependant, il n'y a pas vraiment de raison d'avoir un avertissement sur ce coup là, car la promotion se fait toujours du type dont la taille est la plus petite vers le type dont la taille est la plus grande, et que la promotion est implicite dés le moment où il n'y a pas d'autre correspondance.
    La raison est notée dans mon post précédent (globalement pour le problème que j'ai rencontré : un short casté en int me corrompt tout !). Mais c'est aussi pour la raison que tu cites que je ne réclame qu'un warning de la part du standard .

  18. #18
    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 germinolegrand Voir le message
    La raison est notée dans mon post précédent (globalement pour le problème que j'ai rencontré : un short casté en int me corrompt tout !). Mais c'est aussi pour la raison que tu cites que je ne réclame qu'un warning de la part du standard .
    A ma connaissance (mais je dois avouer n'avoir jamais lu la brique en entier), le standard n'a jamais imposé le moindre warning, et je ne crois absolument pas qu'il soit de son ressort de le faire

    Je comprends ton désappointement, et je comprends ton coté "chat échaudé craint l'eau froide", mais peut être faut il voir ta mésaventure comme un dur rappel de ce que je ne cesse de répéter: la moindre erreur de conception se paye au prix fort

    Peut etre as tu en fait voulu être "trop générique" ou as tu voulu donner trop de responsabilité à une de tes classes
    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. #19
    Membre Expert

    Avatar de germinolegrand
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2010
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Par défaut
    Citation Envoyé par koala01 Voir le message
    A ma connaissance (mais je dois avouer n'avoir jamais lu la brique en entier), le standard n'a jamais imposé le moindre warning, et je ne crois absolument pas qu'il soit de son ressort de le faire

    Je comprends ton désappointement, et je comprends ton coté "chat échaudé craint l'eau froide", mais peut être faut il voir ta mésaventure comme un dur rappel de ce que je ne cesse de répéter: la moindre erreur de conception se paye au prix fort

    Peut etre as tu en fait voulu être "trop générique" ou as tu voulu donner trop de responsabilité à une de tes classes
    Il me semble avoir lu quelques fois des tournures comme "the compiler may advice quelque chose but is not required to". C'est quelque chose comme cela que je demande.

    Pourquoi dès que c'est moi est-ce une erreur de conception ?
    Tu sais déjà à quel point ce genre d'erreur est assez peu adapté à ma façon de coder.

    En outre, non, ce n'est pas une erreur de conception (cf. le lien dans le post de Flob90), mais un bug avéré de compilateur doublé d'une défection du standard. Mon sf:: Packet prenait une enumération dont le type sous-jacent était fixé, et le compilateur choisissais la surcharge int alors que ce n'était pas le type de l'enum. Conclusion, je sérialise un short il se retrouve en int, de l'autre côté je veux évidemment récupérer un short, mais évidemment les données sont corrompues puisque c'est 4 octets qui ont été sérialisés et non 2 ! J'ai fixé ce problème en ajoutant encore plus de responsabilité à sf:: Packet d'ailleurs : https://github.com/germinolegrand/SF...1e2012efdfefd4. Et j'avoue qu'il ne s'en porte que mieux

  20. #20
    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 germinolegrand Voir le message
    Il me semble avoir lu quelques fois des tournures comme "the compiler may advice quelque chose but is not required to". C'est quelque chose comme cela que je demande.
    (ca fait vraiment longtemps que je n'ai plus lu la norme )

    Si la norme peut conseiller d'afficher des avertissements, alors, "on" peut effectivement proposer de le rajouter
    Pourquoi dès que c'est moi est-ce une erreur de conception ?
    Tu sais déjà à quel point ce genre d'erreur est assez peu adapté à ma façon de coder.
    Et tu sais à quel point j'ai un avis contraire

    En outre, non, ce n'est pas une erreur de conception (cf. le lien dans le post de Flob90), mais un bug avéré de compilateur
    Si, en plus, il faut jouer avec un bug du compilateur, évidemment...
    doublé d'une défection du standard.
    Par chance, il évolue... peut etre pas aussi vite qu'on le voudrait, mais il évolue...

    Qu'attend tu pour proposer l'ajout sur la ML adéquate, maintenant qu'il est possible de le faire
    Mon sf:: Packet prenait une enumération dont le type sous-jacent était fixé, et le compilateur choisissais la surcharge int alors que ce n'était pas le type de l'enum.
    Est ce qu sf:acket dispose de la surcharge short

    Si oui, toutes mes excuses, le seul responsable, c'est le compilateur.

    Si non, toutes mes excuses aussi : les tords sont partagés entre le compilateur (pour une grosse part ) et les développeur de SFML
    Conclusion, je sérialise un short il se retrouve en int, de l'autre côté je veux évidemment récupérer un short, mais évidemment les données sont corrompues puisque c'est 4 octets qui ont été sérialisés et non 2 !
    Je reconnais que c'est pas cool
    J'ai fixé ce problème en ajoutant encore plus de responsabilité à sf:: Packet d'ailleurs : https://github.com/germinolegrand/SF...1e2012efdfefd4. Et j'avoue qu'il ne s'en porte que mieux
    Je n'ai vu que le résultat de ton commit, mais je ne peux m'empêcher de penser qu'il serait peut etre temps de faire en sorte que l'opérateur << de sf:: Packet soit basé sur une politique et sur plusieurs traits .

    Cela permettrait sans doute de résoudre de manière plus "globale" ce genre de problème (car je présumes, peut etre à tord, que si tu as eu ce problème avec sf:: Packet, on risque de le retrouver avec d'autres classes sérialisables )

    Maintenant, ce n'est qu'une idée qui me vient directement à l'esprit et je ne sais absolument pas si c'est réalisable de manière cohérente
    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

Discussions similaires

  1. Réponses: 0
    Dernier message: 20/11/2014, 18h44
  2. [Fortran 90] Type entier non signé
    Par nnath dans le forum Fortran
    Réponses: 2
    Dernier message: 17/07/2006, 00h21
  3. Calculer la longueur d'une variable de type entier
    Par juliendeparis dans le forum C
    Réponses: 13
    Dernier message: 08/06/2006, 13h44
  4. [API] résultat d'un Insert sur un champs de type entier
    Par Popoyan dans le forum Bases de données
    Réponses: 3
    Dernier message: 05/06/2006, 14h16
  5. [LG]type entier
    Par fakroun dans le forum Langage
    Réponses: 3
    Dernier message: 20/11/2003, 23h39

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