前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++核心准则ES.106:不要试图通过使用无符号类型避免负值

C++核心准则ES.106:不要试图通过使用无符号类型避免负值

作者头像
面向对象思考
发布2020-06-24 10:41:04
7520
发布2020-06-24 10:41:04
举报

ES.106: Don't try to avoid negative values by using unsigned

ES.106:不要试图通过使用无符号类型避免负值

Reason(原因)

Choosing unsigned implies many changes to the usual behavior of integers, including modulo arithmetic, can suppress warnings related to overflow, and opens the door for errors related to signed/unsigned mixes. Using unsigned doesn't actually eliminate the possibility of negative values.

选择无符号数意味着修改整数的很多无用行为(如含按模运算),这会抑制溢出关联的警告信息,为有符号/无符号数混合计算相关的错误打开了大门。使用无符号数不会真的消除负值的可能性。

Example(示例)

unsigned int u1 = -2;   // Valid: the value of u1 is 4294967294
int i1 = -2;
unsigned int u2 = i1;   // Valid: the value of u2 is 4294967294
int i2 = u2;            // Valid: the value of i2 is -2

These problems with such (perfectly legal) constructs are hard to spot in real code and are the source of many real-world errors. Consider:

在实际的代码中,这些(完全合法的)构造中的隐含的问题很难发现,会带来很多现实世界中的错误。考虑下面的代码:

unsigned area(unsigned height, unsigned width) { return height*width; } // [see also](#Ri-expects)
// ...
int height;
cin >> height;
auto a = area(height, 2);   // if the input is -2 a becomes 4294967292

Remember that -1 when assigned to an unsigned int becomes the largest unsigned int. Also, since unsigned arithmetic is modulo arithmetic the multiplication didn't overflow, it wrapped around.

记住当-1赋给一个无符号整数时,会变成一个最大的无符号整数。同时,由于无符号数学运算是按模运算,乘法运算不会溢出,而是发生回绕。

Example(示例)

unsigned max = 100000;    // "accidental typo", I mean to say 10'000
unsigned short x = 100;
while (x < max) x += 100; // infinite loop

Had x been a signed short, we could have warned about the undefined behavior upon overflow.

如果x是一个有符号短整数,我们会收到一个由于溢出而导致无定义行为的警告。

Alternatives(其他选项)

  • use signed integers and check for x >= 0
  • 使用有符号整数并检查x是否大于0
  • use a positive integer type
  • 使用一个正整数类型
  • use an integer subrange type
  • 使用值域限定的整数类型
  • Assert(-1 < x)
  • 使用断言检查(-1<x)

For example(示例)

struct Positive {
    int val;
    Positive(int x) :val{x} { Assert(0 < x); }
    operator int() { return val; }
};

int f(Positive arg) { return arg; }

int r1 = f(2);
int r2 = f(-2);  // throws
Note(注意)

???

Enforcement(实施建议)

See ES.100 Enforcements.

参考ES.100的实施建议

原文链接

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es106-dont-try-to-avoid-negative-values-by-using-unsigned

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 面向对象思考 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ES.106: Don't try to avoid negative values by using unsigned
  • Reason(原因)
    • Note(注意)
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档