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

d202d95f086dac133648d136afd1ee71.png

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 4294967294int i1 = -2;unsigned int u2 = i1;   // Valid: the value of u2 is 4294967294int 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'000unsigned 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

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


觉得本文有帮助?请分享给更多人。

关注微信公众号【面向对象思考】轻松学习每一天!

面向对象开发,面向对象思考!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值