Lig*_*ica 14 c++ language-lawyer c++11
在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
Run Code Online (Sandbox Code Playgroud)
但:
#include <iostream>
int main()
{
std::cout << ((ssize_t)1 - (unsigned int)5) << '\n';
}
// Output: -4
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)
显然,这是一个非常人为的例子,我理解我在整体推广规则中遵循平台/实现定义的类型等价的各种条款,但在星期四,我的大脑无法解开它们进行严格的评估.
究竟是什么标准规则导致了这些结果?
Col*_*mbo 16
免责声明:我参考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
-hence无符号下溢,值为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).
归档时间: |
|
查看次数: |
526 次 |
最近记录: |