关于unsigned int的建议(江南风格版)

时间:2014-12-03 15:11:28

标签: c++ styles int 32-bit unsigned

视频“江南风格”(我相信你已经听过)在youtube上只有超过20亿的观看次数。事实上,Google表示他们从未预料到视频会超过32位整数......这暗示了Google使用 int 代替unsigned作为其观看计数器的事实。我认为他们不得不重新编写代码以适应更大的视图。

检查其样式指南:https://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Integer_Types

...他们建议“不要使用无符号整数类型”,并给出一个很好的理由:unsigned可能是错误的。

这是一个很好的理由,但可以防范。我的问题是:使用unsigned int

一般编码实践是否错误?

5 个答案:

答案 0 :(得分:13)

Google规则在专业界广泛接受。问题 是无符号整数类型有点破碎,并且有 用于数值时出现意外和不自然的行为;他们 不能作为主要类型工作。例如,数组的索引 可能永远不会消极,但写作是完全合理的 abs(i1 - i2)找到两个指数之间的距离。哪个不会起作用 i1i2有无符号类型。

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

关于"自我记录"使用unsigned:这个 并没有坚持,因为几乎总有很多价值观 变量不能(或不应该)采取,包括许多积极的变量。 C ++ 不具有子范围类型,并且unsigned的定义方式意味着 它也不能真正用作它。

答案 1 :(得分:9)

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

只需抓住Google以外的其他人发布的this article about a bug in the standard Java binary search algorithm,了解为什么必须注意整数溢出。事实上,这篇文章将C ++代码转换为unsigned int,以便保证正确的行为。本文还首先介绍了Java中的一个错误,猜测它们没有unsigned int。但是,它们仍然遇到了整数溢出的错误。

答案 2 :(得分:5)

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

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

答案 3 :(得分:2)

谷歌表示:“有些人,包括一些教科书作者,建议使用unsigned类型来表示从不否定的数字。这是一种自我记录的形式。”

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

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

Google建议:“使用断言记录变量是非负的。不要使用无符号类型。”

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

Pro for Google:如果在调试模式下传递了一个负数,我的代码将有望返回一个越界错误。谷歌的代码保证断言。

Pro for me:我的代码可以支持更大的myArray

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

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

答案 4 :(得分:1)

您具体的问题是:

"使用未签名是不好的做法?"唯一正确的答案可能是没有。这不是坏事。

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

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

CERT IIRC推荐无符号用于缓冲区索引,因为如果你发生溢出,至少你仍然在你自己的缓冲区中,那里有一些内在的安全性。

语言和标准图书馆设计师说了什么(可能是公认智慧的最佳表现形式)。 strlen返回一个size_t,它可能是unsigned(取决于平台),其他答案表明这是一个时代错误,因为闪亮的新计算机具有广泛的体系结构,但这忽略了C和C ++是通用编程语言并且应该在大小上都能很好地扩展的观点平台。

一句话是,这是许多宗教问题之一;当然没有解决,在这些情况下,我通常会将我的宗教信仰用于绿色领域的开发,并与现有的代码库的约定一起用于现有工作。一致性很重要。