2015-06-18 121 views
-4

警告以下行警告:符號和無符號整數表達式的比較[-Wsign-比較]

for(int nPort = 0 ; nPort< (sizeof(nArrOverloadParams)/sizeof(int)) && nRetVal 
        == RET_SUCCESS_VALUE ;nPort++) 
+0

'sizeof()'產生一個無符號的值,所以有什麼不清楚的警告?改爲'unsigned int nPort = 0;' –

+5

當問一個問題時,通常是個好主意來問你的問題。 – Hurkyl

+0

我必須嘗試贏得逆轉徽章! –

回答

0

的警告表示,原則比較可能失敗。有符號值是(1)提升爲無符號類型。如果它是負面的(編譯器不知道它不是,沒有廣泛的分析),那麼推廣到無符號產生一個非常大的值。

的後果是,你保證

std::string("Blah").length() < -5 

這僅僅是極其愚蠢–它的類型,一旦有意義大小值的選擇的結果,但目前是非常次優(但由於需要兼容性而不可能改變)。

作爲一個經驗法則,因此這是一個好主意,

  • 使用符號類型的數字,但

  • 使用無符號類型位級操作。

例如,您可以使用ptrdiff_t(指針差異表達式的結果類型)作爲size_t的簽名版本。

然後,您可以爲數組表示一個有符號大小的函數,例如,

#include <stddef.h> 

namespace cppx { 
    using Size = ptrdiff_t; 

    template< class Item, Size n > 
    auto n_items(Item (&)[n]) 
     -> Size 
    { return n; } 
} 

和環路的相關部分則變爲

using cppx::n_items; 

int overloadedParams[77]; 
for(int port = 0 ; port< n_items(overloadedParams); port++) 

另一種方法是使用一個基於範圍的環,旁路整個問題:

for(int param : overloadedParams) 

如果循環體的邏輯需要索引,則可以添加一個計數器。

循環的行爲是根據以std::beginstd::end表示的等效代碼來定義的。


歷史。據我所知,Dietmar Kuhl認爲功能begin,endn_items的三元組實際上是有用的(這是對簽名大小編程的必要支持),儘管沒有第三個函數的名稱。 C++ 11標準增加了std::beginstd::end,但沒有std::n_itemsstd::extent是一個非常不同的野獸)。


1)在標準這種轉換是由C++ 14§5/ 10限定的「通常的算術轉換」的一部分。

相關問題