Domanda

Oggi ho trovato la seguente:

#include <stdio.h>

int main(){
char x = 255;
int z = ((int)x)*2;

printf("%d\n", z); //prints -2

return 0;

}

Quindi, fondamentalmente sto ottenendo un overflow perché il limite di dimensione è determinata dalle operandi sul lato destro del segno = ??

Perché non il cast a int prima di moltiplicare il lavoro?

In questo caso sto usando un char e int, ma se uso "lungo" e "long long int" (C99), allora ottengo un comportamento simile. E 'generalmente sconsigliati fare aritmetica con operandi di diverse dimensioni?

È stato utile?

Soluzione

char può essere sia firmato o non firmato, a seconda del compilatore.

Nel tuo caso, sembra essere firmato, e 255 è fuori del campo può rappresentare (probabilmente, può rappresentare solo numeri da -128 a 127).

Quindi, il problema si verifica quando si assegna 255 alla variabile char -. Ciò si traduce in un valore definito dall'implementazione, che nel tuo caso, sembra essere -1

Quando si moltiplicano -1 per 2, si ottiene -2. Nessun mistero lì. Il cast di (int) non fa nulla -. Tipi più strette di int sono sempre promossi int o unsigned int prima che i calcoli sono fatti con loro

Altri suggerimenti

Sembra che char è firmato sulla vostra piattaforma. Così il char x = 255 è effettivamente la stessa char x = -1. Il cast a int non importa.

Provare a cambiare quello a:

unsigned char x = 255;

No, non sono sempre un overflow sulla seconda riga (moltiplicazione). Il problema è che il compilatore sta usando signed char per default e 255 overflow e significherà -1. In sostanza, si inizializza x variabile con il valore di -1. Casting -1 a int comporterà -1 (operandi signed avranno accesso esteso in upcasts mentre operandi unsigned otterrà zero estesa).

È possibile forzare il char essere unsigned aggiungendo il prefisso unsigned:

unsigned char x = 255;

Le altre risposte ben spiegare come il vostro esempio "opere", quindi non mi spiegheranno che ancora una volta.

Tuttavia, mi permetta di osservare che se ciò che si desidera utilizzare è un "unsigned 8 bit integer", solo l'uso <stdint.h> di uint8_t già (e le sue 16, 32, compagni a 64 bit) e tenere lontano da tutti i chars, shorts e ints in questo mondo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top