簡體   English   中英

這個循環是否隱式地將 int 轉換為 size_t?

[英]Is this loop implicitly casting an int to size_t?

我在我的程序中遇到了一個錯誤:

for (int i = 0; i < objArray.size() - 1; ++i)

在我的例子中 objArray.size() 是一個 unsigned long long 並且一個空向量減去 1 大約等於 18 quintillion。 我想知道,每次迭代的循環是否都必須將 int 轉換為 unsigned long long? 我檢查了程序集,在使用 int 創建與未優化的 size_t 不同的代碼時,指定 -O2 會生成完全相同的程序集。 這是否意味着它不是隱式轉換?

我不懂匯編,但它生成的代碼是:

test rcx, rcx
je .L32
add rdx, rax

進而 :

cmp rdx, rax
jne .L28

這可能是由編譯器優化引起的。 C++ 標准說有符號整數類型的溢出是未定義的。 在這種情況下, i0開始。 假設i沒有寫入循環中,編譯器因此可以推斷i >= 0 ,因為溢出是未定義的行為並且可以修剪。

通常,對於有符號-無符號比較,必須按照您可以在此處看到的規則將有符號值轉換為無符號類型。 這些規則是比較有符號和無符號類型時編譯器警告的原因(導致混淆,例如-1 > 2U為真)。 在這種情況下,這並不重要。

假設i >= 0和 2-complement 有符號類型,編譯器可以安全地將i重新解釋為unsigned long long因為他知道符號位是0 這就是你的匯編輸出顯示的內容。

現在,我們可以看到確實存在一個錯誤。 假設objArray.size() - 1適合積極簽署int 這會導致i溢出,從而導致未定義的行為,這總是壞消息。

讓我們剖析 (int i = 0; i < objArray.size() - 1; ++i) 的代碼

您正在對 int 和 size_t 進行比較。 當數組為空時,size( )-1 是一個無符號下溢並導致 std::numeric_limits::max( ) 的值。 比較,將有符號/無符號,並使用此處概述的類型提升規則有符號/無符號比較

暫無
暫無

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

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