dépassement de capacité arithmétique parce signé caractères dans un programme C

Nous savons que signed char peuvent avoir des valeurs uniquement à partir de -128 à 127.
mais quand on lance le programme ci-dessous aucun débordement se produit même si le l de sortie dépasse la plage de signé personnage.

#include <stdio.h>


int main()
{
    char i = 60;
    char j = 30;
    char k = 10;
    char l = (i*j)/k;
    printf("%d ", l);

    return 0;
}

la sortie de l est 180 qui est hors de portée pour char l, mais je n'obtiens pas d'erreur.

dans l'autre scénario, si nous prenons le même programme, mais au lieu de la fonction arithmétique si nous avons simplement mis l=180 et essayez d'imprimer alors nous obtenons une réponse incorrecte.

#include <stdio.h>


int main()
{
    char i = 60;
    char j = 30;
    char k = 10;
    char l = 180;
    printf("%d ", l);

    return 0;
}

la réponse que je reçois dans le 2ème cas est -76.
quelqu'un peut-il expliquer pourquoi? même si je suis pratiquement l'exécution de la même chose, mais j'obtiens des résultats différents.

EDIT:

C'est l'exemple classique que les calculs intermédiaires sont réalisés dans int et pas char

donc en 1er quand je fais le calcul, il prend toutes les valeurs de type int et dans la partie plus tard, je suis en mentionnant explicitement comme char.

  • Peut-être que votre compilateur est cassé ? Quel compilateur utilisez-vous ?
  • Le premier extrait n'est pas reproductible: ideone.com/B4b4AJ
  • Je dirais que c'est de l'optimisation. L'expression est juste évaluée comme int droit à l'instruction print. Ou vous n'êtes pas de dire la vérité.
  • Pourquoi l'optimiseur de permis de rompre la troncature de char ?
  • pas de mon compilateur n'est pas cassé , j'ai testé le programme ci-dessus sur les deux ide dire DEVC++ et VS2015 , même vous, vous pouvez essayer de le au-dessus de deux versions d'un même programme et que pouvez-vous voir que les réponses sont différentes, en dépit qu'ils en disent la même logique.
  • Pas sûr que c'est permis.. c'est plutôt la deuxième partie du commentaire.
  • Eugène Sh , monsieur, vous pouvez vous-même vérifier en cours d'exécution sur l'un de vos IDE , j'obtiens des résultats différents à partir du programme.
  • reproduit sur SuSE linux sur IBAN zSeries gcc (SUSE Linux) 4.3.4, niveau d'optimisation -O3
  • Fait-il preuve de la même sans l'optimisation?
  • Je vais essayer ......
  • Sur gcc 4.8.4 je ne peux que reproduire alors que j'ai spécifié unsigned char.
  • C'est de 180 même avec -O0 sur IBM Z
  • Débordement d'entier UB. Votre compilateur optimiseur utilise pour éliminer l'variable complètement. Vite toujours les atouts précise. Ne fonctionne pas dans le 2ème cas, puisque le compilateur a déjà généré -76.
  • Il n'y a pas de dépassement de capacité dans le calcul lui-même, que dans la conversion de char. Et la conversion d'une valeur qui ne rentre pas dans un plus petit nombre entier signé est de type définis par l'implémentation, pas de UB.
  • Mais la mise en œuvre définies par le comportement ne peut pas expliquer le comportement décrit, comme il n'est pas sur le casting seulement ici..
  • Il s'avère être une question intéressante.
  • Je n'ai pas d'offrir une explication (je ne vois pas d'autre explication qu'un compilateur bug ou une erreur de la part de l'OP), j'ai seulement dit que ce n'est pas AC.
  • stackoverflow.com/questions/18195715/... indique qu'il est AC si, comme le résultat du calcul est un nombre entier signé.
  • Mais où est le débordement ici?
  • Le résultat devrait être le même. C'est un compilateur (optimisation) bug.
  • Maintenant, je pense que le problème est du au fait que printfs va_arg n'ont pas en réalité aucune information de type, de sorte que l'entier de la promotion, nous attendons de ne pas réellement se produire, rendant soit AC ou indéterminée. Pas un bug. La différence est dans le contenu de la mémoire d'étendre l
  • le débordement est essayer de s'adapter à 180 dans un (présumé) signed char. Ce qui ferait UB et donc les résultats ne doivent pas être les mêmes. va_arg en fait de promouvoir des types d'entiers plus petits que les int int.
  • Exactement. C'est le problème ici. Il s'attend à ce int pour %d, c'est l'ensemble de la int de la mémoire à la place de char.
  • Lire le fil. Elle est définie par l'implémentation.
  • oh ? stackoverflow.com/questions/23983471/... stackoverflow.com/questions/22844360/...
  • En fait, j'ai mal dits. Var-les arguments de la fonction effectue l'argument par défaut promotions incluent entier promotions.
  • Hm. Dans ce cas, je ne peux pas venir avec quelque chose, mais un bug..
  • Je viens de découvrir votre commentaire indiquant que la conversion de 180, ce qui est un int en char signé UB. Ce n'est pas parce C11 6.3.1.3.p3 membres elle est définie par l'implémentation.
  • Le propriétaire a accepté la réponse qui a déclaré que la réclamation était faux, dans le temps de le dire..
  • Une autre preuve que quelque chose commençant par "Nous savons que ..." ou une expression similaire est mauvais >95% des fois. si char est signé est dépendant de l'implémentation. Et signed char a un **distance minimale de -127..127. peut être beaucoup plus grande, si.
  • Je verrais plutôt explicite de commentaire à ce sujet. Voir aussi Ingo Leonhardts commentaires ci-dessus.
  • Veuillez indiquer votre plate-forme cible (PROCESSEUR, système d'exploitation, compilateur de détails)

InformationsquelleAutor Common Man | 2016-07-04