3

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

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

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

4

6 回答 6

13

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

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

现在,如果我们将其更改为 a deque,我们只更改一行。即使它是一些具有古怪 size_type 的自定义容器,您也会得到温暖、模糊的感觉,一切都会好起来的。这很值得。即使只有无符号/无符号,使用有符号/无符号转换也存在一些棘手的提升问题,这些问题将不可避免地反过来咬你。

于 2009-06-29T19:41:15.117 回答
10

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

在这种情况下,对于这个特定的错误,它可能不是什么大问题——在 32 位平台上,在无符号数转换为负符号值之前,向量中必须有超过 20 亿个条目。获得这样的向量会耗尽你所有的记忆,因此可能无法进入有符号/无符号不匹配的状态。

于 2009-06-29T19:42:17.177 回答
6

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

于 2009-06-29T19:41:41.030 回答
1

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

11111111 < 10000000

于 2009-06-29T19:41:51.530 回答
0

在您的示例的大多数情况下,这无关紧要。但是当你的程序不工作时,你做的第一件事(或应该做的)是确保没有警告,所以这是一个不值得冒险的机会。

确保尽可能少的警告。

于 2009-06-29T19:44:21.617 回答
0

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

于 2009-06-29T20:33:42.750 回答