2012-06-26 18 views
7

Podobnie jak w pytaniu Bitshift and integer promotion?, mam pytanie dotyczące promocji całkowitej przy korzystaniu z lewych bitshift.Integerowa promocja z operatorem <<

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

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

W tym przypadku będzie value8 najpierw promować do unsiged int czy jest to specyficzna realizacja?

6.5.7 bitowe operatory przesunięcia ... 3 Sematics ...
W promocjach całkowitymi są wykonywane na każdym z argumentów. Typ wyniku to tego z promowanego lewego operandu. Jeśli wartość prawego argumentu jest ujemna lub jest równa większa lub równa szerokości promowanego lewego argumentu, zachowanie jest niezdefiniowane.

Mówi, że "Promowane są liczby całkowite na każdym z operandów.", ale jaka jest tu zasada promocji?

Zakładam, że powinien to być convert to int if lesser rank than int, ale nie mogę go znaleźć.

Proszę, ponieważ jeden kompilator (Renesas nc30wa) nie promuje do int, więc wynik jest zawsze 0 dla mojej próbki.

Na tej platformie znak jest 8-bitowy i ma 16 bitów.

+2

Jeśli wartość8 nie jest promowana, jest to błąd kompilatora. –

+1

Dokładnie to jest pytanie, czy jest to błąd lub konkretna implementacja? – jeb

+0

@jeb Zobacz edycję w mojej odpowiedzi, niektóre kompilatory domyślnie wyłączają promocje bezpośrednie i dokumentuje je w dokumentacji kompilatora. Musisz szukać zgodności z ISO w dokumentacji kompilatora. – ouah

Odpowiedz

12

Tekst „promocji całkowite” jest bardzo specyficzna, co, znajdujący się w (na C99) § 6.3.1.1 Booleans, characters, and integers:

Jeśli int może reprezentować wszystkie wartości tego samego typu, to wartość jest przekształcany w int; w przeciwnym razie zostanie przekonwertowany na niepodpisaną wartość int. Są one nazywane promocjami całkowitymi . Wszystkie pozostałe typy są niezmienione przez promocje całkowite.

Więc zakładając, że unsigned char może się odbyć w int, będzie promowany do int. Na tych rzadkich platformach, gdzie unsigned char jest tak szeroki jak int, będzie on promowany do unsigned int.

ten zmienia się tylko nieznacznie w C11:

Jeśli int może reprezentować wszystkie wartości tego samego typu (jak ograniczona przez szerokość, do bitów pola ), wartość przekształca się w int; w przeciwnym razie zostanie przekonwertowany na unsigned int.Są to tak zwane promocje bezpośrednie. Wszystkie pozostałe typy są niezmienione przez promocje o wartości całkowitej z zakresu .

Jeśli określony kompilator nie postępuje zgodnie z tym zachowaniem, oznacza to, że nie jest zgodny. Jednakże, biorąc pod uwagę, że wymieniony kompilator jest przeznaczony dla systemów wbudowanych, nie jest to naprawdę zaskakujące.

Wiele jest zbudowanych do konkretnych celów, a zgodność nie zawsze znajduje się wysoko na liście wymagań. Mogą istnieć flagi kompilatora, które pozwolą mu być bardziej zgodnym ze standardem.


Patrząc na szczególności środowiska, M16C Series,R8C Family C Compiler Package V.5.45 C Compiler (patrz here) ma w przekroju 2.1.4 nc30 Command Line Options, podrozdziale f. Generated code modification options:

-fextend_to_int (-fETI):
          Wykonuje operację po rozszerzeniu danych typu char na typ int. Rozszerzony zgodnie z normami ANSI.

Chociaż podejrzewam, że -fansi jest prawdopodobnie lepszym wyborem, ponieważ obejmuje również kilka innych rzeczy.

3

value8 jest podnoszony do int, przy założeniu, że stopień konwersji unsigned char jest niższy niż stopień konwersji int (zwykle w większości przypadków platformach).

Stopień konwersji liczb całkowitych jest opisany w C99 w 6.3.1.1.

Należy zauważyć, że niektóre kompilatory domyślnie wyłączają reguły promocji całkowitych. Na przykład kompilator MicroChip MPLAB C18. Poszukaj zgodności z ISO w dokumentacji twojego kompilatora.

Powiązane problemy