2015-10-02 18 views
16

Ho riscontrato un problema nel capire perché l'output è diverso in ciascuno di questi casi particolari. Nel codice di esempio una, c'è una promozione variabile come mi aspetto e il risultato è > 6, ma nel codice di esempio B, il risultato è <= 6:Promozione variabile in C

/* **Code a** */ 
puts("Code a\n"); 
unsigned int a = 6; 
int b = -20; 
(a+b > 6) ? puts("> 6\n") : puts("<= 6\n"); 

/* **Code b** */ 
puts("Code b:\n"); 
uint8_t a1 = 6; 
int8_t b1 = -20; 
(a1+b1 > 6) ? puts("> 6\n") : puts("<= 6\n"); 

uscita:

Code a 

> 6 

Code b: 

<= 6 
+0

Dai uno sguardo a: [In un'espressione C in cui sono presenti int unsigned e signed sign, quale tipo verrà promosso a quale tipo?] (Http://stackoverflow.com/questions/2280663/in-ac-expression -where-unsigned-int-and-signed-int-are-present-which-type-will) Spero che ti possa aiutare. – Missu

+0

Fornire un'immagine per l'output testuale? Viene caricato automaticamente quando qualcuno apre questa domanda? Hai un tracker dietro?) Per favore usa solo il taglia e incolla in questi casi. –

+5

Un bell'esempio di post di base, ma ben formato: titolo chiaro, istruzione di difficoltà chiara, codice di esempio, output, output previsto, tag buoni. – chux

risposta

9

Il solito le conversioni aritmetiche vengono eseguite sugli operandi di addizione. Per i tipi interi, questo consiste delle promozioni intere, se necessario, e se i due operandi non hanno lo stesso tipo viene eseguita un'ulteriore conversione per portarli a un tipo comune.

Nel primo caso non ci sono promozioni ma la int operando viene convertito unsigned int perché int non può contenere tutti i possibili valori di unsigned int.

Nel secondo caso entrambi gli operandi vengono promossi a int e rimangono come int poiché hanno un tipo comune.

Per riferimento il progetto di norma C11 nella sezione 6.5.6Operatori additivi dice:

Se entrambi gli operandi hanno tipo aritmetico, le usuali conversioni aritmetiche vengono eseguite su loro.

sezione 6.3.1.8 conversioni aritmetiche usuali dice:

Molti operatori che prevedono operandi di tipo aritmetico causa conversioni e tipi di risultato resa in un modo simile. Lo scopo è di determinare un tipo reale comune per gli operandi e il risultato. Per gli operandi specificati da , ciascun operando viene convertito, senza modificare il dominio di tipo , in un tipo il cui tipo reale corrispondente è il tipo comune reale . Se non diversamente specificato, il tipo reale comune è anche il tipo reale corrispondente del risultato, il cui dominio di tipo è il dominio di tipo degli operandi se sono uguali e complesso . Questo modello è chiamato usuali conversioni aritmetiche

[...]

Altrimenti, promozioni interi vengono eseguite su entrambi gli operandi. Poi le seguenti regole vengono applicate alle operandi promosse

[...]

  • Altrimenti, se l'operando che ha senza segno tipo intero ha rango maggiore o uguale al rango del tipo di altro operando, quindi l'operando con tipo integer segnato convertito al tipo dell'operando con unsigned tipo integer

[...]

Un buon riferimento per la motivazione di questo può essere trovato nella domanda: Why must a short be converted to an int before arithmetic operations in C and C++?.

+0

Ha perfettamente senso ora. Grazie – Lal0ver

+0

Sia le "promozioni integer" che le conversioni necessarie per portare gli operandi a un tipo comune fanno parte delle "solite conversioni aritmetiche". Vedi [N1570] (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) 6.3.1.8. –

+0

@KeithThompson hmmm, non volevo che suonasse altrimenti, ma posso vedere come si legge in questo modo. –