关于未签名int(江南风格版)的建议



视频"江南风格"(我相信你听说过(在YouTube上的观看次数刚刚超过20亿次。事实上,谷歌表示,他们从未期望视频大于 32 位整数......这暗示了谷歌使用 int 而不是unsigned作为他们的视图计数器的事实。我认为他们不得不稍微重写代码以适应更大的视图。

检查他们的风格指南:https://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Integer_Types

。他们建议"不要使用无符号整数类型",并给出了一个很好的理由:unsigned可能有问题。

这是一个很好的理由,但可以防范。我的问题是:使用unsigned int通常是不好的编码实践吗?

谷歌规则在专业圈子里被广泛接受。 问题所在是无符号整数类型有点被破坏,并且有用于数值时的意外和不自然行为;他们不能很好地作为基数类型工作。 例如,数组中的索引可能永远不会是消极的,但写起来很有意义 abs(i1 - i2)查找两个索引之间的距离。 如果出现以下情况,这将不起作用 i1i2具有无符号类型。

作为一般规则,Google样式指南中的此特定规则或多或少对应于语言设计者的意图。任何时候你看到int以外的东西,你都可以假设一个特殊的原因。 如果是因为范围,它将longlong long,甚至int_least64_t. 通常使用无符号类型您正在处理位的信号,而不是变量,或者(至少在unsigned char的情况下(你是处理原始内存。

关于使用unsigned的"自我文档":这站不住脚,因为几乎总是有很多值变量不能(或不应该(接受,包括许多积极的变量。 C++没有子范围类型,定义unsigned的方式意味着它也不能真正用作一个。

该指南具有极大的误导性。盲目地使用int而不是unsigned int并不能解决任何问题。这只会将问题转移到其他地方。在对固定精度整数进行算术运算时,您绝对必须注意整数溢出。如果代码的编写方式不能正常处理某些给定输入的整数溢出,则无论使用 signed 还是 unsigned int s,代码都会被破坏。对于 unsigned int s,您还必须了解整数下溢,对于 double s 和 float s,您必须了解浮点运算的许多其他问题。

看看这篇关于谷歌发布的标准Java二进制搜索算法中的一个错误的文章,为什么你必须注意整数溢出。事实上,正是这篇文章展示了C++代码转换unsigned int保证正确的行为。本文还首先介绍了 Java 中的一个错误,猜猜怎么着,他们没有unsigned int。但是,他们仍然遇到了整数溢出的错误。

对要执行的操作使用正确的类型。 float柜台没有意义。signed int也没有.计数器上的正常操作是print+=1

即使您有一些不寻常的操作,例如打印查看计数的差异,您也不一定有问题。当然,其他答案提到了不正确的abs(i2-i1)但期望程序员使用正确的max(i2,i1) - min(i2,i1)并非没有道理。这确实有signed int的范围问题.这里没有统一的解决方案;程序员应该了解他们正在使用的类型的属性。

谷歌指出:"有些人,包括一些教科书作者,建议使用unsigned类型来表示永不负的数字。这是作为自我记录的一种形式。

我个人使用 unsigned int s 作为索引参数。

int foo(unsigned int index, int* myArray){
    return myArray[index];
}

谷歌建议:"使用断言记录变量是非负数的。不要使用无符号类型。

int foo(int index, int* myArray){
    assert(index >= 0);
    return myArray[index];
}

谷歌专业版:如果在调试模式下传递负数,我的代码有望返回越界错误。谷歌的代码是保证断言的。

对我来说是专业人士:我的代码可以支持更大的myArray

我认为实际的决定因素归结为,您的代码有多干净?如果清理所有警告,则编译器何时警告您,您将清楚地知道何时尝试将有符号变量分配给无符号变量。如果你的代码已经有一堆警告,编译器的警告就会丢失。

最后一点:谷歌说:"有时 gcc 会注意到这个错误并警告你,但通常不会。我还没有在Visual Studio上看到这种情况,检查负数和从有符号到无符号的分配总是被警告。但是如果你使用gcc,你可能会小心。

你的具体问题是:

"使用无符号是不好的做法吗?"唯一正确的答案可能是否定的。 这不是坏做法。

有许多风格指南,每个都有不同的重点,虽然在某些情况下,一个组织,鉴于他们典型的工具链和部署平台可能会选择不使用未签名的产品,但其他工具链和平台几乎要求使用它。

谷歌似乎得到了很多尊重,因为他们有一个很好的商业模式(并且可能像其他人一样雇用一些聪明的人(。

CERT IIRC 建议对缓冲区索引使用无符号,因为如果您确实溢出,至少您仍然会在自己的缓冲区中,那里有一些内在的安全性。

语言和标准库设计者怎么说(可能是公认智慧的最佳代表(。 strlen 返回一个size_t,它可能是无符号的(依赖于平台(,其他答案表明这是一个不合时宜的错误,因为闪亮的新计算机具有广泛的架构,但这忽略了 C 和 C++ 是通用编程语言,应该在大小平台上很好地扩展。

底线是,这是许多宗教问题之一;当然没有解决,在这些情况下,我通常会与我的宗教一起进行绿地开发,并在现有工作中遵循代码库的现有惯例。 一致性很重要。

相关内容

  • 没有找到相关文章

最新更新