2010-09-02 6 views
3

le code suivant:c question bitwise conversion de négation

signed char sc = ~0xFC; 
unsigned char uc = ~0xFC; 

lors de la compilation me donne les avertissements suivants:

integer conversion resulted in truncation 
integer conversion resulted in truncation 
  1. pourquoi dois-je obtenir ces avertissements
  2. comment puis-je écrire mon code, de sorte que je ne reçois pas ces avertissements (sans utiliser #pragmas)

Thanx,

J'utilise compilateur IAR pour 8051,

obtenez-vous des avertissements similaires lors de la compilation en utilisant d'autres compilateurs?

+0

+1 pour ne pas ignorer les avertissements. – Thanatos

Répondre

2

En C, arithmétiques sont effectuées au moins à la taille de int. Cela signifie que ~0xFC renverra un int. Encore plus, cette valeur est 0xFF03, ce qui est bien au-delà de la plage de char (signé ou non).

Par conséquent, l'affectation donnera les deux avertissements. Vous pouvez essayer

signed char sc = ~0xFC & 0xFF; 

pour voir si le compilateur sait que le résultat est dans la plage de char (gcc ne se plaindra pas après avoir ajouté le & 0xFF). Vous pouvez également essayer d'ajouter un casting explicite:

signed char sc = (signed char)~0xFC; 
// also possible: 
// signed char sc = ~(signed char)0xFC; 

ou, la valeur peut être facilement calculée, pourquoi pas seulement

signed char sc = 3; 
+0

ITYM '0xFFFFFF03' (@ 32 bits), et' 3' dans la dernière ligne. –

+0

@Paul: Je ne suis pas sûr si le 'int' est 32 bits, 8051 étant une architecture 16 bits, selon Wikipedia. – kennytm

+0

votre réponse est incorrecte dans le sens où le '~' peut très bien être appliqué à n'importe quel type entier, en particulier à 'char', puis il renvoie un' char'. La chose malheureuse est qu'il n'y a pas une telle chose comme une constante littérale en C, même la notation ''\ 0xx'' est' int'. Donc, vous devrez le faire comme Jack propose dans sa réponse pour obtenir une constante de caractère et tout fonctionne bien. –

6

Parce que littéraux hexadécimaux sont considérés comme int quand ils sont écrits comme vous l'avez fait 0xFC. . pour éviter l'avertissement juste les jeter à tronquer le numéro à seulement 1 octet:

~((char) 0xFC) 

0xFC est considéré 0x000000FC sur 32 bits architecture, donc quand vous appliquez pas vous obtenez 0xFFFFFF03, cela signifie que lorsque vous affectez ce résultat à un char, les 3 octets les plus pertinents sont simplement ignorés et le compilateur vous en avertit.