编译器警告

时间:2009-06-29 19:39:21

标签: c++ compiler-warnings unsigned signed

假设我有这个(C ++或C)代码:

vector<int> my_vector;
for (int i = 0; i < my_vector.size(); i++) {
    my_vector[i] = 0;
}

我不在乎它是否做得对。重要的部分是for循环声明。 编译器给出了有符号/无符号的不匹配,因为size()返回unsigned int而不是signed符号。将i更改为未签名有多重要?我将循环计数器声称为习惯中的int,但如果这是一个潜在的错误,我将强迫自己摆脱这种习惯。

6 个答案:

答案 0 :(得分:13)

从技术上讲,i应该是vector<int>::size_type。你应养成在代码中使用typedef的习惯:

typedef vector<int> VectorType;
VectorType my_vector;
for (VectorType::size_type i = 0; i < my_vector.size(); i++) {
    my_vector[i] = 0;
}

现在,如果我们将其更改为deque,我们只会更改一行。即使它是一个古怪的size_type的自定义容器,你会得到温暖,模糊的感觉,一切都会好的。这非常值得。即使只使用未签名/签名,使用签名/未签名转换也会有一些棘手的推广问题,这些问题不可避免地会让您感到厌烦。

答案 1 :(得分:10)

我会说这非常重要 - 您应该将警告编译为错误,并努力修复所有警告。如果你在代码中留下这样的问题,很容易养成忽视警告的习惯,或者让像这样的误报淹没警告,指出真正的问题。

在这种情况下,对于这个特定的错误,它可能不是什么大问题 - 在32位平台上,在无符号将包装成负的有符号值之前,你必须在向量中有超过20亿个条目。要获得这样的向量会耗尽你的所有内存,所以可能无法进入签名/无符号不匹配的状态。

答案 2 :(得分:6)

在矢量大小超过INT_MAX的情况下,这可能很重要。如果向量的大小大于可以在带符号的int中表示的最大值,那么您的循环将永远不会终止。

答案 3 :(得分:1)

嗯,重要的是因为有符号整数有符号,所以我可以一路向上变成负值,然后无论它有多大,它仍然会小于size(),它没有任何符号。

  

11111111&lt;千万

答案 4 :(得分:0)

在你的例子的大多数情况下,无所谓。但是当你的程序不起作用时,你做(或应该)的第一件事就是确保没有警告,所以这是一个不值得冒的机会。

确保警告尽可能少。

答案 5 :(得分:0)

如上所述,使用vector :: size_type;或使用迭代器循环遍历向量。 确保将所有自己的警告视为错误。