“有符号/无符号不匹配”警告(C4018),循环递减

时间:2016-08-14 19:07:18

标签: c++ visual-c++

我应该如何处理C ++代码中的“签名/无符号不匹配”警告:

for (int i = vector.size() - 1; i >= 0; --i) // OK
{
    if (i < vector.size() / 2) // warning C4018: '<': signed/unsigned mismatch
        // ... 
}

(一个人为的例子,但它证明了这个问题。)

How do I deal with "signed/unsigned mismatch" warnings (C4018)?说使用size_t作为循环变量,但这不适用于终止于0的递减循环。它在没有警告的情况下编译,但是整数溢出(或者它是否下溢? )在运行时变为4294967295。

3 个答案:

答案 0 :(得分:5)

首先,学习一些成熟的习语,这些习语允许您使用unsigned类型编写递减周期。这是C和C ++中绝对必要的技能。 E.g。

for ([some unsigned type] i = N; i-- > 0; )
{
  // Process i-th element
}

for ([some unsigned type] i = N; i > 0; )
{
  --i;
  // Process i-th element
}

(请注意,i的初始值为N,而不是N - 1。)

或者你甚至可以使用更自然的&#34;方法

for ([some unsigned type] i = N - 1; i != -1; --i)
{
  // Process i-th element
}

其次,开始使用适当的无符号类型进行向量索引。在你的情况下

for (auto i = vector.size() - 1; i != -1; --i)

for ([your vector type]::size_type i = vector.size() - 1; i != -1; --i)

这将解决您的警告问题。

或者,你可以选择一个“失败者”的出路&#34;并使用显式强制转换

来禁止警告
if ((unsigned) i < vector.size() / 2) 

或只是#pragma warning(disable: 4018)

答案 1 :(得分:1)

或者:

for(size_t j = 0; j < vector.size(); j++){
    size_t i = vector.size() - 1 - j;
    ...
}

答案 2 :(得分:0)

我会为适配器写一个索引范围。

向后写,它会调整范围以反向迭代。

这给了我们:

for(auto i:backwards(indexes_into(container))){

结果不易出错,在使用时有效且更清晰(只要您信任您的实用程序代码)。

两种解决方案都存在于boost,rangesv3和我的各种SO帖子中。