簡體   English   中英

size_t vs int 警告

[英]size_t vs int warning

對於以下類型的代碼,我總是收到以下警告。

std::vector v;
for ( int i = 0; i < v.size(); i++) {
}

warning C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data

我知道size()返回size_t ,只是想知道忽略此警告是否安全,或者我應該將所有循環變量設為size_t類型

如果您可能需要在向量中保存超過INT_MAX個項目,請使用size_t 在大多數情況下,這並不重要,但我使用size_t只是為了使警告 go 消失。

更好的是,使用迭代器:

for( auto it = v.begin(); it != v.end(); ++it )

(如果您的編譯器不支持 C++11,請使用std::vector<whatever>::iterator代替auto

C++11 還可以更輕松地選擇最佳索引類型(如果您在某些計算中使用索引,而不僅僅是下標v ):

for( decltype(v.size()) i = 0; i < v.size(); ++i )

什么是size_t
size_t對應於語言運算符sizeof返回的整數數據類型,並在 header 文件(以及其他文件)中定義為unsigned integral type

可以將size_t轉換為int嗎?
如果您確定 size 永遠不會大於INT_MAX ,則可以使用強制轉換。

如果您正在嘗試編寫可移植代碼,這是 不安全的,因為,

64 bit Unix中的size_t64 bits
64 bit Windows中的size_t32 bits

因此,如果您將代碼從 Unix 移植到 WIndows 並且如果以上是環境,您將丟失數據。

建議的答案

鑒於警告,建議將i設為unsigned integral type ,甚至更好地將其用作size_t類型。

忽略這個警告是否安全,或者我應該將所有循環變量設為 size_t 類型

不,您正在接受 class 的 integer 溢出攻擊。 如果向量大小大於MAX_INT (並且攻擊者有辦法做到這一點),您的循環將永遠運行,從而導致拒絕服務的可能性。

不過,從技術上講, std::vector::size返回std::vector::size_type

您應該為循環計數器變量使用正確的符號。 (實際上,對於大多數用途,您需要無符號整數而不是循環的有符號整數)

問題是您混合了兩種不同的數據類型。 在某些架構上, size_t是 32 位 integer,在其他架構上是 64 位。 您的代碼應該正確處理這兩者。

由於size()返回一個size_t而不是 int ),那么這應該是您與之比較的數據類型。

std::vector v;
for ( size_t i = 0; i < v.size(); i++) {
}

這是 Bjarne Stroustrup 的另一個觀點: http://www.stroustrup.com/bs_faq2.html#simple-program

for (int i = 0; i<v.size(); ++i) cout << v[i] << '\n';

是的,我知道我可以將 i 聲明為 vector::size_type 而不是普通的 int 來安靜地發出一些超可疑編譯器的警告,但在這種情況下,我認為這太迂腐和分散注意力。

這是一個權衡。 如果您擔心 v.size() 可能 go 高於 2,147,483,647,請使用 size_t。 如果您在循環中使用 i 不僅僅是查看向量內部,並且您擔心微妙的有符號/無符號相關錯誤,請使用 int。 根據我的經驗,后一個問題比前一個問題更普遍。 您的體驗可能會有所不同。

另請參閱為什么 size_t 未簽名? .

暫無
暫無

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

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