2012-06-26 33 views
7

Simile alla domanda Bitshift and integer promotion?, ho una domanda sulla promozione di interi quando si usano i bitshift di sinistra.Promozione intera con l'operatore <<

unsigned int test(void) 
{ 
    unsigned char value8; 
    unsigned int result; 

    value8 = 0x12; 
    result = value8 << 8; 
    return result; 
} 

In questo caso, sarà la prima value8 promuovere a unsiged int o è specifica di attuazione?

6.5.7 bitwise operatori di spostamento ... 3 sematics ...
Le promozioni interi vengono eseguite su ogni operando. Il tipo del risultato è quello dell'operando sinistro promosso. Se il valore dell'operando di destra è negativo o è maggiore o uguale alla larghezza dell'operando di sinistra promosso, il comportamento non è definito.

Si dice che lo "Le promozioni intere vengono eseguite su ciascuno degli operandi.", ma qual è la regola di promozione?

Suppongo che dovrebbe essere convert to int if lesser rank than int, ma non riesco a trovarlo.

Chiedo questo, come un compilatore (Renesas nc30wa) non promuove a int, quindi il risultato è sempre 0 per il mio campione.

Su questa piattaforma, un char è 8 bit wide e int 16 bit.

+2

Se value8 non viene promosso, si tratta di un bug del compilatore. –

+1

Questa è esattamente la domanda, è un bug o un'implementazione specifica? – jeb

+0

@jeb Vedere la modifica nella mia risposta, alcuni compilatori disabilitano le promozioni intere per impostazione predefinita e lo documentano nella documentazione del compilatore. Devi cercare la conformità ISO nella documentazione del compilatore. – ouah

risposta

12

La frase "le promozioni interi" è una cosa molto specifica, che si trova a (per C99) Sezione 6.3.1.1 Booleans, characters, and integers:

Se un int può rappresentare tutti i valori del tipo di originale, il valore viene convertito in un int; in caso contrario, viene convertito in un int unsigned. Questi sono chiamati le promozioni di numero intero . Tutti gli altri tipi sono invariati dalle promozioni intere.

Quindi supponendo che il unsigned char può essere tenuto in una int, che sarà promosso ad un int. Su quelle rare piattaforme in cui lo unsigned char è largo come un int, verrà promosso a un valore unsigned int.

Questo è cambiato solo leggermente in C11:

Se un int può rappresentare tutti i valori del tipo originale (come limitato dalla larghezza per un campo bit ), il valore viene convertito in un int; in caso contrario, viene convertito in un int. senza segno.Queste sono chiamate promozioni intere. Tutti gli altri tipi sono invariati dalle promozioni intere .

Se un compilatore specifico non segue questo comportamento, non è realmente conforme. Tuttavia, dato che il compilatore che hai elencato è per sistemi embedded, non è davvero sorprendente.

Molti sono costruiti per scopi specifici e la conformità non è sempre in cima alla lista dei requisiti. Potrebbero esserci flag di compilazione che gli consentiranno di conformarsi più strettamente allo standard.


Guardando il tuo particolare ambiente, il M16C Series,R8C Family C Compiler Package V.5.45 C Compiler (vedi here) presenta in sezione 2.1.4 nc30 Command Line Options, comma f. Generated code modification options:

-fextend_to_int (-fETI):
          Esegue l'operazione dopo l'estensione dei dati di tipo char al tipo int. Esteso secondo gli standard ANSI.

anche se sospetto che lo -fansi sia probabilmente una scelta migliore poiché copre anche alcune altre cose.

3

value8 viene promosso int, assumendo la posizione di conversione unsigned char è inferiore al rango di conversione int (solitamente il caso su molte piattaforme).

I gradi di conversione degli interi sono descritti in C99 in 6.3.1.1.

Si noti che alcuni compilatori disabilitano le regole di promozioni intere per impostazione predefinita. Ad esempio, compilatore MicroChip MPLAB C18. Cerca la conformità ISO nella documentazione del tuo compilatore.

Problemi correlati