Straszne odpowiedzi w bród
Ozgur Ozcitak
Kiedy przesyłasz ze znaku podpisanego na niepodpisany (i odwrotnie), wewnętrzna reprezentacja liczby nie zmienia się. Zmiana polega na tym, jak kompilator interpretuje bit znaku.
To jest całkowicie błędne.
Mats Fredriksson
Kiedy dodawana jest jedna zmienna bez znaku i jedna ze znakiem ze znakiem (lub dowolna operacja binarna), obie są niejawnie konwertowane na bez znaku, co w tym przypadku dałoby ogromny wynik.
To też jest złe. Bez znaku int mogą być promowane do int, jeśli mają taką samą precyzję ze względu na wypełnienie bitów w typie bez znaku.
smh
Twoja operacja dodawania powoduje, że int zostanie przekonwertowany na int bez znaku.
Źle. Może tak, a może nie.
Konwersja z unsigned int na signed int zależy od implementacji. (Ale obecnie prawdopodobnie działa tak, jak oczekujesz na większości platform).
Źle. Jest to niezdefiniowane zachowanie, jeśli powoduje przepełnienie lub wartość zostaje zachowana.
Anonimowy
Wartość i jest konwertowana na unsigned int ...
Źle. Zależy od dokładności int względem wartości int bez znaku.
Taylor Price
Jak już wcześniej udzielono, możesz bez problemu przesyłać między podpisanymi i niepodpisanymi.
Źle. Próba zapisania wartości poza zakresem liczby całkowitej ze znakiem powoduje niezdefiniowane zachowanie.
Teraz mogę wreszcie odpowiedzieć na pytanie.
Jeśli dokładność int będzie równa unsigned int, u zostanie podniesione do int ze znakiem, a otrzymasz wartość -4444 z wyrażenia (u + i). Teraz, jeśli u i ja mamy inne wartości, możesz uzyskać przepełnienie i niezdefiniowane zachowanie, ale z tymi dokładnymi liczbami otrzymasz -4444 [1] . Ta wartość będzie miała typ int. Ale próbujesz zapisać tę wartość w unsigned int, aby następnie został rzutowany na int bez znaku, a wartość, którą otrzyma wynik, będzie (UINT_MAX + 1) - 4444.
Jeśli dokładność wartości typu unsigned int będzie większa niż liczba int, int ze znakiem zostanie podwyższona do liczby int bez znaku, dając wartość (UINT_MAX + 1) - 5678, która zostanie dodana do drugiej liczby int bez znaku 1234. Czy u i i inne wartości, które powodują, że wyrażenie wykracza poza zakres {0..UINT_MAX} wartość (UINT_MAX + 1) zostanie dodana lub odjęta, dopóki wynik NIE znajdzie się w zakresie {0..UINT_MAX) i nie wystąpi żadne niezdefiniowane zachowanie .
Co to jest precyzja?
Liczby całkowite mają bity wypełniające, bity znaku i bity wartości. Liczby całkowite bez znaku nie mają oczywiście bitu znaku. Ponadto gwarantuje się, że znak bez znaku nie będzie zawierał bitów wypełniających. Liczba bitów wartości, które ma liczba całkowita, określa jej dokładność.
[Gotchas]
Samo makro rozmiar makra nie może służyć do określenia dokładności liczby całkowitej, jeśli obecne są bity wypełniające. A rozmiar bajtu nie musi być oktetem (osiem bitów), jak określono w C99.
[1] Przelew może wystąpić w jednym z dwóch punktów. Albo przed dodaniem (podczas promocji) - gdy masz int bez znaku, który jest zbyt duży, aby zmieścić się w int. Przepełnienie może również wystąpić po dodaniu, nawet jeśli unsigned int znajdował się w zakresie int, po dodaniu wynik może nadal przepełniać.