簡體   English   中英

int32_t 到 uint64_t 轉換的順序

[英]Order of int32_t to uint64_t casting

C++標准是否保證integer轉換既加寬又去掉符號是符號擴展還是零擴展?

快速測試:

int32_t s = -1;
uint64_t u = s;

在 Xcode 下產生 0xFFFFFFFFFFFFFFFF,但這是首先定義的行為嗎?

當你這樣做

uint64_t u = s;

[dcl.init]/17.9適用,其中規定:

正在初始化的 object 的初始值是初始化表達式的(可能轉換的)值。 如有必要,將使用標准轉換序列 ([conv]) 將初始化表達式轉換為目標類型的 cv 非限定版本; 不考慮用戶定義的轉換。

如果我們查看[conv] ,在積分轉換下,我們有

否則,結果是與源 integer 模 2 N一致的目標類型的唯一值,其中 N 是目標類型的寬度。

所以你保證會發生的是 -1 成為可能表示的最大數字,-2 比它少一,-3 比 -2 少一,依此類推,基本上它“環繞”。


實際上,

unsigned_type some_name = -1;

是為該無符號 integer 類型創建具有最大值的變量的規范方法。

您可以在其他答案中找到標准措辭。

但是為了幫助您形成一個直觀的心理 model 擴大轉換,將這些視為一個兩步過程會很有幫助:

  1. 值的符號擴展或零擴展。 如果值是有符號類型,則使用符號擴展。 這里int32_t符號擴展為int64_t 在 x86 上,類型的有符號性決定了使用的是MOVSX還是MOVZX指令。
  2. 將擴展值轉換為目標類型(更改符號)。 這里int64_t被轉換為uint64_t 它涉及 0 條匯編指令,因為寄存器是無類型的,編譯器只是將包含int32_t符號擴展結果的寄存器視為uint64_t

請注意,該標准沒有指定這些步驟,它只是指定了所需的結果。

積分轉換部分:

[conv.integral/3]:否則,結果是與源 integer 模2 N一致的目標類型的唯一值,其中N是目標類型的寬度。

換句話說,環繞“最后發生”。

暫無
暫無

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

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