簡體   English   中英

整數提升如何在C Cast上運行?

[英]How does integer promotion work on C Cast?

我被一個意想不到的整數促銷所困擾,讓我感到奇怪。 在編譯器中是否一致是否在顯式轉換之前進行促銷?

讓我解釋。 有一個有符號的8位變量,如

int8_t s8a = -128; //<-- 0x80

分配給無符號16作為uint16_t s16b = s8a + 1; 我希望升級到一個更大的整數0xFF81然后分配,這是一個常見的事故,並考慮在像MISRA C這樣的文件上。但是以uint16_t s16b = (uint16_t)s8a的方式明確地轉換為無符號類型我本來期望s8a立即失去其“簽名”,然后零擴展到16位,以給出0x0080但實際上相反的情況發生,因為它得到符號擴展然后失去其簽名時,鑄造和分配給0xFF80

這種行為標准還是C的另一種未定義行為?

這與整數提升無關,但與類型轉換無關。 在您的情況下,該過程由C11標准很好地定義- 6.3.1.3有符號和無符號整數(p2)

..如果新類型是無符號的,則通過重復加或減一個可以在新類型中表示的最大值來轉換該值,直到該值在新類型的范圍內。

所以這里0xFF80 = 0xFFFF + (-128) + 1 ,因為0xFFFF是可以在uint16_t表示的uint16_t

給定初始化int8_t s8a = -128;

  1. 在初始化的情況下uint16_t s16b = s8a + 1;
    1. 在表達式s8a + 1s8a(int8_t)-128 )中的值被提升為(int)-128並且添加(int)1以給出(int)-127
    2. 在初始化中uint16_t s16b = (int)-127; (int)-127轉換為(uint16_t)0xff81並存儲在s16b
  2. 在初始化的情況下uint16_t s16b = (uint16_t)s8a + 1;
    1. 在表達式(uint16_t)s8as8a(int8_t)-128 )中的值被轉換為(uint16_t)0xff80
    2. 在表達式(uint16_t)0xff80 + 1
      • 如果INT_MAX >= 65535 ,那么(uint16_t)0xff80將轉換為(int)0xff80並添加(int)1以賦予(int)0xff81
      • 如果INT_MAX < 65535 ,則將1轉換為(uint16_t)1並添加(uint16_t)0xff80以給出(uint16_t)0xff81
    3. 在初始化中uint16_t s16b = (int)0xff81; (當INT_MAX >= 65535 ),或初始化uint16_t s16b = (uint16_t)0xff81; (當INT_MAX < 65535 ):
      • 如果INT_MAX >= 65535 ,則(int)0xff81轉換為(uint16_t)0xff81並存儲在s16b
      • 如果INT_MAX < 65535 ,則(uint16_t)0xff81存儲在s16b

在兩種情況下, s16b被初始化為值(uint16_t)0xff81

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM