web-dev-qa-db-fra.com

Attention: débordement dans la conversion constante implicite

Dans le programme suivant, la ligne 5 donne overflow warning comme prévu, mais étonnamment, la ligne 4 ne donne aucun avertissement dans GCC: http://www.ideone.com/U0BXn

int main()
{
    int i = 256;
    char c1 = i;    //line 4
    char c2 = 256;  //line 5
    return 0;
}

Je pensais que les deux lignes devraient donner overflow warning. Ou y a-t-il quelque chose qui me manque?


Le sujet qui m'a amené à faire cette expérience est le suivant: vérification de type typedef?

Là j'ai dit ce qui suit (que j'ai effacé de ma réponse, parce que quand je l'ai lancé, ça ne s'est pas passé comme prévu):

//However, you'll get warning for this case:

typedef int  T1;
typedef char T2;

T1 x = 256;     
T2 y = x; //possible overflow warning! (but it doesn't give warning :()
13
Nawaz

-Wall n'inclut pas beaucoup d'options. -Wconversion est l'un d'entre eux et vous avertit du comportement qui vous intéresse.

Voir http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

11
Crazy Eddie

Dans le cas général d'attribution d'une valeur int à un objet char, le compilateur ne sait pas si int est en dehors de la plage char.

Regardez l'avertissement réel de plus près:

warning: overflow in implicit constant conversion

C'est dans ce cas particulier, où une constante est convertie en char que le compilateur est en mesure de vous avertir. De même, si vous avez changé la déclaration de i en const:

const int i = 256;

vous obtiendrez également l'avertissement, car la valeur affectée à c2 est une expression constante.

Notez également que l'avertissement est quelque peu trompeur car la conversion ne "déborde" pas techniquement. Le dépassement arithmétique donne un comportement non défini en C++. Une conversion restrictive (telle que int en char, si int a une plage plus grande que char) génère une conversion définie par l'implémentation.

8
James McNellis

La ligne 5 est une erreur évidente que tout compilateur peut voir directement et toujours une erreur. La ligne 4 nécessiterait au moins certains analyses de flux de données pour détecter l'erreur. Cela n’est peut-être pas fait avec les paramètres utilisés sur le site, ou peut-être que les rédacteurs du compilateur n’ont pas jugé cela assez important pour le comprendre.

1
Bo Persson

Depuis GCC 4.3, la sémantique de -Wconversion a été mise à jour pour détecter les conversions implicites susceptibles de modifier une valeur, mais vous devez également activer -Wsign-conversion, car vous ne recevrez pas d'avertissement pour le code susceptible de modifier le signe d'un nombre dû à la contrainte entre les types signés et non signés.

Contrairement à ce que dit Crazy Eddie, avant GCC 4.3 (qui n'avait pas encore été publié), -Wconversion ne vérifiait pas de manière générique les problèmes liés à la conversion de type implicite, etc. Au lieu de cela, il a vérifié si votre programme se comporterait différemment de celui qu’il aurait utilisé s’il avait utilisé des prototypes de fonctions K & R à l’ancienne.

Cela signifiait non seulement que cela ne donnait pas d'avertissement sur tous les problèmes de conversion de type/coercition implicites, mais aussi que du code de qualité donnait un avertissement inutile. Et bien sûr, vous n’obtiendrez aucune erreur avec g++ car de tels prototypes ne sont de toute façon pas valides en C++.

0
Anonymous