实际案例:
案例1:
有些人, 包括一些教科书作者, 推荐使用无符号类型表示非负数. 这种做法试图达到自我文档化. 但是, 在 C 语言中, 这一优点被由其导致的 bug 所淹没. 看看下面的例子:
循环永远不会退出.png
上述循环永远不会退出! 有时 gcc 会发现该 bug 并报警, 但大部分情况下都不会. 类似的 bug 还会出现在比较有符合变量和无符号变量时. 主要是 C 的类型提升机制会致使无符号类型的行为出乎你的意料.
案例2:
uint64_t last_route_time_ ;//上次心跳时间,在别处赋值
//本函数通过取本地时间来获得心跳时间,用时间差判断是否超时
bool IsOverTime(int overtime)
{
if (overtime == 0)
{
return false;
}
time_t c = time(0);
if (c - last_route_time_ > overtime)
{
return true;
}
return false;
}
正常情况下,c - last_route_time_
会是一个正数,函数没问题。当有人在某个时间点,将服务器的本地时间回调了,那么c - last_route_time_
会得到一个很大的正数,使得函数判断一直超时。
另外还有一些其它不规范的写法:1、overtime == 0
应该改为0 == overtime
2、 time_t c
命名太简单,建议 time_t c urrent_time
结论:
使用确定大小的整型,如int16_t、int32_t、int64_t
等整型,除位组外尽量不使用无符号型,使用断言声明变量为非负数
定义:
C++ 没有指定整型的大小. 通常人们假定 short
是 16 位, int
是 32 位, long
是 32 位, long long
是 64 位.
优点:
保持声明统一.
缺点:
C++ 中整型大小因编译器和体系结构的不同而不同.
分析:
<stdint.h> 定义了 int16_t, uint32_t, int64_t
等整型, 在需要确保整型大小时可以使用它们代替 short, unsigned long long
等. 在 C 整型中, 只使用 int. 在合适的情况下, 推荐使用标准类型如 size_t
和 ptrdiff_t
.
如果已知整数不会太大, 我们常常会使用 int, 如循环计数. 在类似的情况下使用原生类型 int. 你可以认为 int 至少为 32 位, 但不要认为它会多于 32 位. 如果需要 64 位整型, 用 int64_t 或 uint64_t.
对于大整数, 使用 int64_t.
不要使用 uint32_t 等无符号整型, 除非你是在表示一个位组而不是一个数值, 或是你需要定义二进制补码溢出. 尤其是不要为了指出数值永不会为负, 而使用无符号类型. 相反, 你应该使用断言来保护数据.
如果您的代码涉及容器返回的大小(size),确保其类型足以应付容器各种可能的用法。拿不准时,类型越大越好。
小心整型类型转换和整型提升(acgtyrant 注:integer promotions, 比如 int 与 unsigned int 运算时,前者被提升为 unsigned int 而有可能溢出),总有意想不到的后果。
网友评论