2013-03-06 14 views
6

ten drukuje kod B2Integer promocja - jakie są kroki

short a=-5; 
unsigned short b=-5u; 
if(a==b) 
    printf("A1"); 
else 
    printf("B2"); 

czytałem o całkowitą promocji, ale to wciąż dla mnie jasne, jak to działa w tym przykładzie? Czy ktoś może dokładnie opublikować kroki, które wykonuje kompilator w rozszerzaniu/obcinaniu wartości?

+0

którego kompilatora używasz? –

+0

[this] (http://en.cppreference.com/w/cpp/language/implicit_cast) może być przydatne. – juanchopanza

+0

Integer promotion dzieje się tylko w wyrażeniu "a == b" - czy to wszystko, o co pytasz? –

Odpowiedz

8

Omówmy kodzie:

short a = -5; 

a = -5, który pasuje do krótkiego. Na razie tak łatwo.

unsigned short b = -5u; 

-5u środki stosuje jednoargumentowy - operatorowi stałej 5u. 5u to (unsigned int) 5, a unary - nie ma promocji, więc kończy się 4294967291, czyli 2^32-5. (Aktualizacja: Trochę się myliłem w mojej oryginalnej odpowiedzi, zobacz skrypt testowy, który pokazuje, że ta wersja jest tutaj poprawna http://codepad.org/hjooaQFW)

Teraz, gdy wstawi się ją do pliku b, jest obcinana do niepodpisanego skrótu (zwykle 2 bajty) , więc b = 65531, czyli 2^16-5.

if(a == b) 

W tym wierszu, aib są promowane do ints, więc porównanie może się odbyć poprawnie. Gdyby zostali promowani do szortów, b potencjalnie zawijałby się. Gdyby zostali awansowani do niepodpisanych krótkich spodenek, to potencjalnie zawijali.

To tak jakby powiedzieć: if((int) a == (int) b). I a = -5, więc (int) a = -5, i b = 65531, więc (int) b = 65531, ponieważ ints są większe niż szorty.

+0

Nie powiedziałbym, że "-5u" nie ma sensu - jest dobrze zdefiniowane przez standard. –

+3

Um, '-5u' jest całkowicie sensowne. Stosuje '-' do stałej liczb całkowitych' 5u'. –

+0

Uderzasz w punkt, który mnie interesuje: więc PRZED -5 zapisuje się w krótkiej zmiennej "a" ... jej stała wartość jest traktowana jako liczba całkowita, prawda? Jestem głęboko zainteresowany tym punktem –

3
a == b 

a i b oba promowany do int w powyższym wyrażeniu.

unsigned short b=-5u; 

W deklaracji -5U przekształca się unsigned short przez środki konwersji całkowitej (C99 6.3.1.3p2 stosuje się tutaj) i staje się bardzo duża wartość.

(C99 6.3.1.3p2) „W przeciwnym razie, jeżeli nowy typ jest podpisany wartość jest przekształcany przez wielokrotne dodanie lub odjęcie o jeden więcej niż wartość maksymalna, która może być reprezentowana w nowego typu do wartości jest w zakresie nowego typu. "

b wartość jest następnie (unsigned short) ((unsigned int) USHRT_MAX + 1 -5) który (unsigned short) 65531 jeśli USHRT_MAX jest (unsigned short) 65535.

Więc co masz jest:

(short) -5 == (unsigned short) 65531

co jest równoważne po całkowitej promocji obu argumentów do:

-5 == 65531

co odpowiada 0.

+0

re "W systemie uzupełnienia dwójki", cóż, w ten sposób niezależnie od reprezentowanej liczby całkowitej, ponieważ święty standard wymaga, aby był binarny, a ponieważ 5 jest o wiele mniejszy niż minimalny wymagany zakres, a ponieważ standard wymaga arytmetyki niepodpisanej do modulo 2^n, gdzie n jest liczbą bitów reprezentacyjnych. Dla, powiedzmy, 32-bitowego 'unsigned' i 16-bitowego' unsigned short' wyrażenie '-5u' samo w sobie daje wartość 2^32-5, a następnie ta wartość modulo 2^16 jest koniecznie 2^16- 5. ponownie, niezależnie od reprezentowanej liczby całkowitej. –

+0

@ Cheersandhth.-Alf Zgadzam się, usunąłem to zdanie tuż przed twoim komentarzem. Zacząłem od systemu * na systemie uzupełnienia dwójki *, ponieważ początkowo chciałem dodać informacje o zmianie (braku) reprezentacji. – ouah

0

short do unsigned short jest przekształcenie (a więc mający stopień konwersji)

short do int jest promocja (a więc mający promocji rangę)

Gorące są korzystne ze względu na konwersji rankingu. Promocje pojawiają się podczas operacji arytmetycznych i innych. Konwersje występują, gdy tylko przechowujemy jeden typ integralny w innym. Operacje arytmetyczne mogą powodować zarówno konwersje, jak i promocje, aby wymusić typy razem. Inny przykład:

unsigned int u = 2; 
int i = 2; 
u + i; 

i przekształca się (bez promocji) do unsigned.

Twoja wartość jest konwertowana na większą wartość, ponieważ zawija się ze względu na to, że jest unsigned. Następnie są promowane na int. Tak więc z tego powodu a != b.