int
而不是unsigned
。我认为他们必须稍微重新编写代码来容纳更大的观看量。查看他们的样式指南:https://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Integer_Types。他们建议“不要使用无符号整数类型”,并给出一个很好的原因:unsigned
可能存在漏洞。这是一个好的理由,但可以防范。我的问题是:一般情况下使用unsigned int
是不良编码习惯吗?int
而不是unsigned
。我认为他们必须稍微重新编写代码来容纳更大的观看量。查看他们的样式指南:https://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Integer_Types。他们建议“不要使用无符号整数类型”,并给出一个很好的原因:unsigned
可能存在漏洞。这是一个好的理由,但可以防范。我的问题是:一般情况下使用unsigned int
是不良编码习惯吗?谷歌规则在专业圈中被广泛接受。问题在于,无符号整数类型有点失效,并且在用于数字值时具有意外和不自然的行为;它们不能很好地作为基数类型。例如,数组索引可能永远不会是负数,但是编写 abs(i1 - i2)
来查找两个索引之间的距离是完全有道理的。如果使用无符号类型,则此方法将无法工作。
通常情况下,谷歌样式指南中的这个特定规则更或多或少对应于语言设计人员的意图。如果您看到的不是 int
,则可以假定有一个特殊原因。如果是由于范围,则将使用 long
或 long long
,甚至是 int_least64_t
。通常使用无符号类型表示您正在处理位,而不是变量的数值,或者(至少在使用 unsigned char
的情况下)表示您正在处理原始内存。
关于使用 unsigned
的“自说明性”:这并不能保持,因为变量几乎总是不能(或不应该)采用许多正值,包括许多正值。 C++ 没有子范围类型,并且 unsigned
的定义方式意味着它实际上无法用作子范围类型。
abs(i1-i2)
没有意义,但我喜欢clang对它的警告。 - Cubbi<cstdlib>
而不是浮点数版本的<cmath>
,那么std::abs(i1 - i2)
甚至无法编译通过。在gcc中,我得到了一个“error: call of overloaded ‘abs(unsigned int)’ is ambiguous”的错误。 - b4handsize_type
(无符号)时遵循此指南而不遇到所有已签名/未签名的比较警告?您只需将vector::size()
的结果转换为有符号整数吗? - Emile Cormierint
而不是 unsigned int
并不能解决问题,只是把问题转移到别处。在对定点整数进行算术运算时,你必须绝对注意整数溢出。如果你的代码以某些给定的输入方式编写,无法优雅地处理整数溢出,则无论你使用 signed
还是 unsigned int
,你的代码都是有问题的。使用 unsigned int
时,你还必须注意整数下溢,而在使用 double
和 float
时,你还必须注意许多与浮点算术相关的其他问题。
只需查看由谷歌发布的有关标准Java二分搜索算法漏洞的文章,就可以了解为什么您必须注意整数溢出。事实上,该文章展示了C++代码将类型转换为unsigned int
以保证正确行为。文章还从一个Java中的漏洞开始介绍,猜猜怎么着,他们没有unsigned int
。然而,他们仍然遇到了整数溢出的问题。
在进行操作时,请使用正确的数据类型。对于计数器来说,float
并不合适,signed int
也不是。计数器的常规操作包括print
和+=1
。
即使您有一些不寻常的操作,例如打印观看次数的差异,您也不一定会遇到问题。当然,其他答案提到了不正确的代码abs(i2-i1)
,但是期望程序员使用正确的代码 max(i2,i1) - min(i2,i1)
也不是不合理的。这个代码对于signed int
存在范围问题,因此没有统一的解决方案;程序员应该理解他们正在使用的数据类型的属性。
int foo(unsigned int index, int* myArray){
return myArray[index];
}
谷歌建议:使用断言来指定变量为非负数。不要使用无符号类型。
int foo(int index, int* myArray){
assert(index >= 0);
return myArray[index];
}
谷歌的优势:如果在调试模式下传递了一个负数,我的代码有望返回越界错误。谷歌的代码保证会断言。
我的优势:我的代码可以支持更大的myArray
大小。
我认为最终决定因素在于,你的代码有多干净?如果你清理了 所有警告,那么当编译器警告你尝试将有符号变量赋值给无符号变量时,就会很清楚了。如果你的代码已经有了一堆警告,编译器的警告可能会被忽略。
最后注意一点:谷歌说:“有时gcc会注意到这个bug并警告你,但通常不会。” 在Visual Studio上,我没有看到这种情况,针对负数和从有符号赋值到无符号的检查总是会被警告。但如果你使用gcc,你可能需要小心。
size_t
成为无符号类型的最初动机。这在16位机器上是有效的(当时非常普遍),但今天并不是很相关。问题在于C++(和C)的无符号类型不能很好地模拟整数,甚至不能很好地模拟非负整数集合,因此应该避免使用它们。 - James Kanzeabs(i1-i2)
合法,则必须得到两个值之间的差异。 - James Kanze<cstdlib>
,而不是浮点数版本的 <cmath>
,则 std::abs(i1 - i2)
甚至无法编译通过。在 gcc 中会出现 error: call of overloaded ‘abs(unsigned int)’ is ambiguous
的错误提示。 - b4hand
i
是“无符号整数”时,他们使用i >= 0
作为条件 - 那太愚蠢了。当然,这个条件总是成立的。实际上,在这种情况下,“无符号整数”已经完成了它的工作!它永远不会是负数! - Joseph Mansfieldsize_t
**和ptrdiff_t
。" - Anton Savin