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. #21
    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
    Points : 3 892
    Points
    3 892
    Par défaut
    Disons que sf:: Packet n'est pas une classe sérialisable, c'est elle qui sérialise, je règle donc le problème pour toutes mes sérialisations (j'ai d'ailleurs soumis à discussion mon fix dans les issues de la SFML où la discussion est vive https://github.com/LaurentGomila/SFML/issues/129).
    Et oui la classe dispose de la surcharge short.
    Et pour la politique, je ne peux pas trop me permettre de faire des modifications sauvages aux classes-même de la SFML ^^

    Qu'attend tu pour proposer l'ajout sur la ML adéquate, maintenant qu'il est possible de le faire
    Ce débat n'a d'autre but que d'étayer cette demande en réalité .

  2. #22
    En attente de confirmation mail

    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 : 33
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Bonsoir,

    Je vais vous exposer les comportements attendus pour les 3 premiers appels, et vous présenter une logique (construite de manière ad hoc) qui en rend compte.

    Pour les 3 premiers appels :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    short_or_int(var_short)   ; //short
    int_or_long(var_short)    ; //int
    long_or_longlong(var_int); //ambiguë
    Le "principe premier" du C++ (et d'autre langage) c'est le principe de moindre surprise. Dont le corollaire pourrait être : si il y a un doute, ne rien faire.

    Notre problématique est la résolution des surcharges lors d'une seule séquence de conversion (un seul paramètre). Ce problème se résume donc à ordonner les séquences de conversions (implicites), dans chacun des cas :
    • short -> short ou short -> int
    • short -> int ou short -> long
    • int -> long ou int -> long long

    (Dans notre cas toutes les séquences sont "simples", mais la problématique ne serait pas différente avec une séquence plus complexe (*))

    Dans la logique proposée par Koala, l'ordre est total, la logique de la norme est tout autre et se rapproche plus d'ordonner des classes d'équivalence de ces conversions. De manière plus simple c'est une logique en 4 étapes :
    • Définir des groupes de conversions, ils sont fixés. Ces groupes ne sont pas si éloignés de la logique proposé par Koala : 3 groupes, Exact, Promotion, Conversion.
      • Exact : C'est ce qu'avait exprimé Koala avec l'idée si c'est le bon alors c'est la meilleur solution.
      • Promotion : C'est ce qu'avait exprimé Koala avec l'idée d'aller vers le type le plus adapté à l'architecture, et on peut rajouter au contexte.
      • Conversion : C'est l'ensemble des autres conversion qui ont un sens.
    • Associer à chaque séquence de conversion un groupe, la logique est ici :
      • Si il y a une conversion de la séquence qui appartient au groupe Conversion, alors la séquence appartient au groupe Conversion.
      • Sinon, si il y a une conversion de la séquence qui appartient au groupe Promotion, alors la séquence appartient au groupe Promotion.
      • Sinon la séquence appartient au groupe Exact.

      Cette logique reste cohérente.
    • Ordonner les groupes, la logique proposée par la norme est Exact > Promotion > Conversion.
    • Définir un ensemble complémentaire de règles qui permet d'ordonner des séquences d'un même groupe (**).

    Au final l'ordre n'est pas total, si lors de la considération de l'ensemble des séquence possible il y a plusieurs maximum, alors l'appel est ambigu, sinon l'appel utilise la séquence maximal.

    Il reste à définir le groupe de certaines conversions dans notre cas :
    • A -> A appartient à Exact
    • A -> int si A est un type d'entier et A < int appartient à Promotion
    • A -> B si A et B sont des types d'entier et A différent de B appartient à Conversion

    On est assez proche de la logique proposée par Koala.

    Appliquons ceci à nos 3 appels :
    • short -> short ou short -> int, la première appartient au groupe Exact et la seconde au groupe Promotion, Exact est meilleur que Promotion, l'appel n'est donc pas ambiguë et short -> short est favorisé.
    • short -> int ou short -> long, la première appartient au groupe Promotion et la seconde au groupe Conversion, Promotion est meilleur que Conversion, l'appel n'est donc pas ambiguë et short -> int est favorisé.
    • int -> long ou int -> long long, les deux appartiennent au groupe Conversion et il n'existe pas de règle complémentaire, l'appel est donc ambiguë.


    Cette logique rend compte correctement du comportement pour les 3 premiers appels, la question que je vous propose maintenant est, en vous appuyant sur cette logique, de déterminer le comportement et la logique pour les 3 derniers appels. C'est à dire : comment prendre en compte les types déclaré par les énumération au sein de ces différents différent groupe, notamment avec le type sous-jacent ?

    Bien entendu le nombre de groupe reste fixé, l'ordonnancement entre les groupe aussi. La logique doit donc se construire sur :
    • Associer (logiquement) les conversions enum -> A (ou A est un type d'entier) a un groupe (**)
    • Éventuellement définir une règle complémentaire qui ordonnerait une conversion enum -> A par rapport à d'autre conversion au sein d'un même groupe.


    Je rappel aussi qu'il a été évoqué qu'on pourrait logiquement s'attendre à une symétrie entre les trois premiers appels et les trois seconds appels. Avec ce qu'on vient de dire, on pourrait donc envisager :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    short_or_int(val_short)   ; //short
    int_or_long(val_short)    ; //int
    long_or_longlong(val_int); //ambiguë
    Cependant est-ce que les règles à définir pour obtenir un tel comportement sont les plus logiques ?

    (*) Ça implique d'autre règle pour définir ce qu'est une séquence et dans quel ordre la faire, on ne va pas s'y intéresser ici. Notons cependant qu'une séquence ne peux contenir au maximum qu'une seule conversion de chaque groupe. C'est à dire qu'une séquence peut contenir une Promotion et une Conversion, mais pas 2 Promotions ou 2 Conversions par exemple.
    (**) Aucun de ces règles ne s'applique dans nos 3 premiers cas.
    (***) Le groupe Exact est par nature celui des conversions relatives au changement lvalue/rvalue et de qualification const/volatile (et quelques autres détails). Y mettre autre chose n'est pas forcément illogique mais pourrait produire des résultats étonnants.

  3. #23
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    En fait, je crois que tu as oublié, dans ton raisonnement, que la norme prévoit que la taille des types primitifs respecte l'inégalité
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sizeof(char)<=sizeof(short)<=sizeof(int)<=sizeof(long)<=sizeof(long long)
    dans le cas où ambigüité il a, cette règle peut permettre de la lever dans le cadre de la "politique du moindre effort" généralement suivie par le compilateur:

    Il aura en effet "moins de mal" à promouvoir un int en long qu'à promouvoir un int en long long parce qu'il pourra se permettre un décalage des bits (a priori) moins important, tout comme il aura (a priori toujours) moins de bits à mettre à la valeur correcte
    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

  4. #24
    En attente de confirmation mail

    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 : 33
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    @koala01: Non, pour les conversions (les Promotions uniquement en réalité) ce ne sont pas les sizeof qui sont utilisés, mais la notion de rank, qui est long long > long > int > short (ordre stricte).

    Il n'y a pas de Promotion de int en long ni de int en long long, il y a juste Conversion, et elles sont au même niveau : il y a ambiguïté entre les deux.

    Testés sous deux compilos, et comme ce sont des règles du C++03, voir C++98, pour les 3 premiers appels, je pense que les compilateurs sont à jour sur ce point.

    NB: J'ai construit cette logique depuis la norme directement, je ne l'ai pas inventé (et ce n'est probablement pas celle que j'aurais eu par intuition). D'où le terme logique ad hoc (elle est adapté à la norme).

  5. #25
    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
    Points : 3 892
    Points
    3 892
    Par défaut
    Pour ma part la logique ad hoc semble se tenir, excepté que je demande encore et toujours un warning pour le 2e. Passer le 3e en ambigu ne me semble pas dénué de bon sens, l'argument que j'avais avancé pour le long était simplement d'imiter int, et c'est un argument que je prenais à contre-cœur afin de trouver une justification à l'exception de la 2e. Si une logique permet de faire la différence entre le cas 2 et le cas 3 je l'accepte volontiers.

    Afin de garantir le comportement que j'évoquais qui prévaudrait qu'une enum soit convertie sans ambiguïté à son type sous-jacent, je propose de créer un nouveau groupe, le groupe Equivalence : il contient le type sous-jacent fixé (*) d'une énumération si son typage est faible.

    Le nouvel ordre serait Exact > Equivalence > Promotion > Conversion.

    Cela garantie la non-ambiguïté lors de la conversion d'un enum vers son type sous-jacent, sans pour autant rendre ambigu la conversion lorsque se présentent à la fois le type de l'enum et son type sous-jacent, ce qui est le problème d'ajouter le type sous-jacent au groupe Exact.

    Cela ne casse aucune compatibilité ascendante, pas même avec la norme C++11, contrairement à l'ajout du type sous-jacent au groupe Exact comme on l'a vu plus haut.

    (*) à débattre, en effet bien que cela prémunisse d'une conversion non désirée et instable pour les enum dont le type sous-jacent n'est pas fixé (j'emprunte ici le vocabulaire de la norme différencier les types sous-jacents explicites/implicites), cela pourrait causer des difficultés si la détermination du type sous-jacent est faite en amont dans l'analyse du code.

  6. #26
    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
    Points : 3 892
    Points
    3 892
    Par défaut
    En faisant le tour des papers, ceci (http://www.open-std.org/jtc1/sc22/wg...2012/n3323.pdf) a attiré mon attention : en effet cela concerne notre sujet !

  7. #27
    En attente de confirmation mail

    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 : 33
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Citation Envoyé par germinolegrand Voir le message
    en effet cela concerne notre sujet !
    Pas vraiment non, le papier traite des fonctions de conversions et des conversions depuis les types issue de classes. Deux éléments totalement absents de notre discussion.

  8. #28
    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
    Points : 3 892
    Points
    3 892
    Par défaut
    Mea culpa, je l'ai lu trop vite.

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