# C++核心准则ES.102：使用有符号数进行数学运算

ES.102: Use signed types for arithmetic

ES.102：使用有符号数进行数学运算

### Reason（原因）

Because most arithmetic is assumed to be signed; x - y yields a negative number when y > x except in the rare cases where you really want modulo arithmetic.

Example（示例）

Unsigned arithmetic can yield surprising results if you are not expecting it. This is even more true for mixed signed and unsigned arithmetic.

```template<typename T, typename T2>
T subtract(T x, T2 y)
{
return x - y;
}

void test()
{
int s = 5;
unsigned int us = 5;
cout << subtract(s, 7) << '\n';       // -2
cout << subtract(us, 7u) << '\n';     // 4294967294
cout << subtract(s, 7u) << '\n';      // -2
cout << subtract(us, 7) << '\n';      // 4294967294
cout << subtract(s, us + 2) << '\n';  // -2
cout << subtract(us, s + 2) << '\n';  // 4294967294
}
```

Here we have been very explicit about what's happening, but if you had seen us - (s + 2) or s += 2; ...; us - s, would you reliably have suspected that the result would print as 4294967294?

Exception（例外）

Use unsigned types if you really want modulo arithmetic - add comments as necessary noting the reliance on overflow behavior, as such code is going to be surprising for many programmers.

Example（示例）

The standard library uses unsigned types for subscripts. The built-in array uses signed types for subscripts. This makes surprises (and bugs) inevitable.

```int a[10];
for (int i = 0; i < 10; ++i) a[i] = i;
vector<int> v(10);
// compares signed to unsigned; some compilers warn, but we should not
for (gsl::index i = 0; i < v.size(); ++i) v[i] = i;

int a2[-2];         // error: negative size

// OK, but the number of ints (4294967294) is so large that we should get an exception
vector<int> v2(-2);
```

Use gsl::index for subscripts; see ES.107.

Enforcement（实施建议）

• Flag mixed signed and unsigned arithmetic
• 标记有符号数和无符号数混用的数学运算。
• Flag results of unsigned arithmetic assigned to or printed as signed.
• 标记将无符号数学运算的结果赋值给有符号数或者作为有符号数print输出的情况。
• Flag negative literals (e.g. -2) used as container subscripts.
• 标记使用负值作为容器下标的情况。
• (To avoid noise) Do not flag on a mixed signed/unsigned comparison where one of the arguments is sizeof or a call to container .size() and the other is ptrdiff_t.
• （为了避免误判）当一个参数是sizeof或者container.size()的返回值，而另一个参数是ptrdiff_t的时候，不要标记有符号数/无符号数混合的比较操作。

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es102-use-signed-types-for-arithmetic

0 条评论

• ### C++核心准则ES.76:避免使用goto语句​

Readability, avoidance of errors. There are better control structures for humans...

• ### C++核心准则C.131: 避免无意义的getters和setters‍

A trivial getter or setter adds no semantic value; the data item could just as w...

• ### C++核心准则ES.87:不要在条件语句中增加多余的==或!=

ES.87: Don't add redundant == or != to conditions

• ### 油猴+上这些优质脚本才是神器

一开始接触油猴的时候我内心感觉有点抗拒，但是还是安装了，好像啥都不能干，说好的浏览器必备插件呢？没啥卵用啊？幻想和现实的落差，太大了。。。

• ### 机器学习之决策树二-C4.5原理与代码实现

本文系作者原创，转载请注明出处:https://www.cnblogs.com/further-further-further/p/9435712.html

• ### [Go]当把json解析到interface{}时 , 对应的真正类型

如果解析json时 , 把json解析到map[string]interface , 那值所对应的真正类型是下面这样的

• ### Excel小技巧44：缩减工作表行列数

Excel以前的工作表只有256列65636行，现如今已扩大到16384列1048576行。然而，有时候我们可能只想用户在工作表中一个小范围的区域进行编辑，如下...

• ### 前端知识点总结 ： Vue

作用：将表达式执行的结果 输出当调用元素的innerHTML中；还可以将数据绑定到视图。

• ### Nginx反向代理proxy

这篇文章主要介绍了Nginx反向代理proxy_cache_path directive is not allowed错误解决方法,需要的朋友可以参考下

• ### 机器学习技术的发展与结构搜索的诞生

伴随着人工智能技术的飞速发展，语音识别、机器翻译等各项科技名词已不是传统意义上被企业家束之高阁的前景应用，更不是研究人员讳莫如深的复杂概念，它们已经伴随着大数据...