为什么这种表达未签名
Why is this expression being unsigneded?
on x86_64 centos 7 gcc 4.8.5 c 11:
#include <iostream>
int main()
{
std::cout << ((ssize_t)1 - (size_t)5) << 'n';
}
// Output: 18446744073709551612
但是:
#include <iostream>
int main()
{
std::cout << ((ssize_t)1 - (unsigned int)5) << 'n';
}
// Output: -4
和i686 Centos 6 GCC 4.8.2 C 11,它们都给出4294967292
,所以我必须这样做:
#include <iostream>
int main()
{
std::cout << ((ssize_t)1 - (ssize_t)5) << 'n';
}
// Output: -4
显然,一个极为人为的例子,我知道我根据平台/实施定义的等价符合整体促销规则的各个条款评估。
到底是什么标准规则导致我取得这些结果的序列?
免责声明:我是指C 17的最新N4606草案第5条第11段。我引用和引用的措辞包含在N3337的第9段中,该段实际上与C 11标准相同,并且在C 14的FD中也以该形式相同,因此此答案也适用于这些标准。
假设ssize_t
和size_t
的等级相等,在您的第一种情况下,[Expr]/(11.5.5)适用:
否则,两个操作数应转换为对应于该的无符号整数类型 具有签名整数类型的操作数类型。
1将转换为 ssize_t
的无符号版本,因此应为 size_t
&mdash;因此,无符号的下流流量,值为2 sizeof(size_t)*8
-4。
对于您的第二种情况,假设unsigned
的等级小于ssize_t
的等级,而后者可以保持所有前者的值;请参阅[Expr]/(11.5.4):
否则,如果具有签名整数类型的操作数类型可以代表所有值 具有无符号整数类型的操作数类型,具有无符号整数类型的操作数应 用签名的整数类型转换为操作数的类型。
即。5
将转换为ssize_t
,因此我们得到负面结果。如果ssize_t
的排名不高于unsigned
,我们将获得2 sizeof(unsigned)*8
-4;相反,如果ssize_t
无法持有unsigned
的所有值,我们再次获得负面结果,因为我们属于上述(11.5.5)。
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 为什么在全局范围内使用"extern int a"似乎不行?
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 为什么会发生堆损坏
- 为什么使用 "this" 指针调用派生成员函数?
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 为什么比较运算符如此快速
- 为什么 Serial.println(<char[]>);返回随机字符?
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 为什么不;名字在地图上是按顺序排列的吗
- 我的字符计数代码计算错误.为什么
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 为什么 std::unique 不调用 std::sort?
- 既然存在危险,为什么项目要使用-I include开关
- 为什么在运行时没有向我们提供有关分段错误的更多信息?