2015-06-18 82 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限定的“通常的算术转换”的一部分。

相关问题