C++核心準(zhǔn)則ES.106:不要試圖通過使用無符號類型避免負(fù)值

ES.106: Don't try to avoid negative values by using?unsigned
ES.106:不要試圖通過使用無符號類型避免負(fù)值
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.
選擇無符號數(shù)意味著修改整數(shù)的很多無用行為(如含按模運算),這會抑制溢出關(guān)聯(lián)的警告信息,為有符號/無符號數(shù)混合計算相關(guān)的錯誤打開了大門。使用無符號數(shù)不會真的消除負(fù)值的可能性。
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:
在實際的代碼中,這些(完全合法的)構(gòu)造中的隱含的問題很難發(fā)現(xiàn),會帶來很多現(xiàn)實世界中的錯誤??紤]下面的代碼:
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.
記住當(dāng)-1賦給一個無符號整數(shù)時,會變成一個最大的無符號整數(shù)。同時,由于無符號數(shù)學(xué)運算是按模運算,乘法運算不會溢出,而是發(fā)生回繞。
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是一個有符號短整數(shù),我們會收到一個由于溢出而導(dǎo)致無定義行為的警告。
Alternatives(其他選項)
use signed integers and check for?x >= 0
使用有符號整數(shù)并檢查x是否大于0
use a positive integer type
使用一個正整數(shù)類型
use an integer subrange type
使用值域限定的整數(shù)類型
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); // throwsNote(注意)
???
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
覺得本文有幫助?請分享給更多人。
關(guān)注微信公眾號【面向?qū)ο笏伎肌枯p松學(xué)習(xí)每一天!
面向?qū)ο箝_發(fā),面向?qū)ο笏伎迹?/span>
