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 :

Retour de fonction inattendue avec gcc 4.7.2 et 4.8.0


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 199
    Points : 106
    Points
    106
    Par défaut Retour de fonction inattendue avec gcc 4.7.2 et 4.8.0
    Bonjour à tous,

    J'ai un problème confirmé avec le code ci-dessous, l'addition de deux int16_t me renvoi un int! Est-ce que c'est un comportement normal? Parce que du coup je suis obligé d'employer un static_cast sur le résultat car sinon je prends des warnings de gcc.

    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
    #include <iostream>
     
    template<typename T>
    struct f{
        static constexpr const char *str = "unknown"; };
     
     
    template<>
    struct f<int>{
        static constexpr const char *str = "int"; };
     
     
    template<>
    struct f<int16_t>{
        static constexpr const char *str = "int16_t"; };
     
     
     
    int main(){
        std::cout << f<double>::str << std::endl;
        std::cout << f<int16_t>::str << std::endl;
     
     
        int16_t a(0), b(0);
        std::cout << f< decltype(a+b) >::str << std::endl;
    }
    Et si dessous la sortie :

    Merci beaucoup d'avance !

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 630
    Points : 30 694
    Points
    30 694
    Par défaut
    Salut,

    Ce n'est, a priori, pas impossible, dans le sens où un int16_t peut effectivement être promu de manière tout à fait légale en int et dans le sens où la somme de deux int16_t peut effectivement être supérieure à valeur maximale de ce type.

    En effet, tu risque une perte de donnée si tu réduits le champs de valeurs possibles à un int16_t en essayant d'en additionner deux autres: soit tu risques de te retrouver avec une valeur négative alors qu'elle aurait du être positive, soit tu perds, purement et simple tout ce qui correspond à une valeur supérieure à 65636 et quelques ( avec le risque d'obtenir une valeur négative au passage ).

    Il serait, à mon avis, globalement dangereux d'avoir un autre comportement de celui-ci du fait de ce problème de dépassement des limites, même si je peux concevoir que, sous certaines conditions, il puisse s'avérer utile d'être sur que le résultat sera bel et bien considéré comme un int16_t.

    Malheureusement, je ne vois pas très bien comment résoudre ce problème, à moins de supprimer purement et simplement la spécialisation utilisant un int ce qui aurait pour résultat de le faire passer dans le cas de base (f<T>)

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 199
    Points : 106
    Points
    106
    Par défaut
    Le code ci-dessous n'est qu'à titre d'exemple. J'utilise la somme de deux int16_t dans un contexte où je suis toujours sûr de ne pas dépasser, et je suis obligé d'utiliser un int16_t.

    Mais quand j'ajoute deux int32_t, cela veut dire que le résultat est codé sur un int64_t ?
    Et pour l'ajout de deux int64_t alors ?

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 630
    Points : 30 694
    Points
    30 694
    Par défaut
    Non, cela veut dire que les différents types respectent des contraintes de promotion et que le type dont on part du principe qu'il est le plus adapté est souvent l'int (parce que sa taille s'adapte particulièrement bien aux différents accumulateurs).

    Ainsi, un char (généralement 8bits) peut être promu en un short (généralement 16 bits) qui peut être promu en un int (généralement 32 bits) qui peut être promu en long (long) (disons, pour faire simple, 64 bits).

    Il y aura "forcément" un moment où tu ne pourras plus promouvoir d'avantage ton entier, simplement... parce qu'il n'existe aucun type d'entier qui permette de représenter une taille supérieure, et donc, il y aura "forcément" un moment où la somme de deux entiers risque de "dépasser" la limite de valeur.

    Mais le mieux, si tu veux avoir la certitude que ta structure utilise bel et bien la spécialisation "int16_t", est encore de ne pas profiter de la déduction de type (qui aura tendance à tendre vers le type int car il s'agit du "type le plus adapté"), mais bien de déclarer clairement l'objet comme étant de type f<int16_t>.

    Il faut en effet savoir que le compilateur est naturellement paresseux et qu'il va systématiquement rechercher la spécialisation "qui lui demandera le moins de travail".

    comme il a tendance à considérer toutes les constantes de compilation entières comme des int, il va "naturellement" considérer que c'est cette spécialisation particulière qui est "celle qui lui demande le moins de travail" et donc, comme la spécialisation "la mieux adaptée"

Discussions similaires

  1. [AC-2010] Problème inattendu avec la fonction Choisir() dans QBE
    Par sellig60 dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 06/08/2014, 14h27
  2. Réponses: 1
    Dernier message: 21/12/2012, 19h35
  3. Réponses: 11
    Dernier message: 26/03/2008, 00h12
  4. fonction return () avec retour de plusieurs valeurs
    Par nuphius dans le forum Langage
    Réponses: 4
    Dernier message: 06/01/2007, 18h44
  5. Fonction traditionnelle avec retour
    Par ze veritable farf dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 29/08/2006, 15h48

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