rai*_*ner 3 c c++ language-lawyer
考虑一下C++程序的以下部分; 打印到控制台的值作为注释给出.
{ // case 1
unsigned int x = 10;
unsigned int y = 20;
std::cout << "u/u x - y: " << x-y << std::endl; // 4294967286
}
{ // case 2
int x = 10;
int y = 20;
std::cout << "s/s x - y: " << x-y << std::endl; // -10
}
{ // case 3
unsigned int x = 10;
int y = 20;
std::cout << "u/s x - y: " << x-y << std::endl; // 4294967286
}
{ // case 4
int x = 10;
unsigned int y = 20;
std::cout << "s/u x - y: " << x-y << std::endl; // 4294967286
}
Run Code Online (Sandbox Code Playgroud)
我试图弄清楚C++(尝试使用gcc 4.7.2)如何从表达式定义类型(更具体地说,它的签名).对于情况1,3和4,通常的算术转换应该将两个值都提升为unsigned int:
10 = b00000000000000000000000000001010
20 = b00000000000000000000000000010100
Run Code Online (Sandbox Code Playgroud)
然后,它会做一个2的补码来得到-20并添加它:
10 = b00000000000000000000000000001010
-20 = b11111111111111111111111111101100
b11111111111111111111111111110110
Run Code Online (Sandbox Code Playgroud)
将其解释为无符号整数,并得到4294967286 - 非常好.
显然,对于案例2,您得到相同的计算/结果; 但是,通常的算术转换应该导致两个操作数被解释为带符号的int,并且结果似乎也被解释为有符号整数.
从此,我推断,如果操作数在通常的算术转换后签名,则结果将被签名.否则,结果是无符号的.
所以,我的问题是:
+,*等会工作方式相同,但对于移位和逻辑操作?编辑:这似乎与C++ 11类型(签名+无符号)有关?,但是我的问题的关键部分似乎从那里接受的答案中遗漏了:在通常的算术转换之后,表达式的结果是否总是两种操作数的类型?
转换遵循整数转换等级原则.简而言之,当积分操作数为:
完全相同,没有转换发生.
在相同大小的情况下,unsigned优先.
不同尺寸,较小的转换为更大.如果较大的是无符号,则较小的也将转换为无符号.
此转换将操作数转换为相同的类型,这也是结果的类型.
它受intC++ 11标准的影响.它也密切相关int和unsigned int.这些适用于哪些运营商的内容包含在各个运营商的子章节中[expr]§9.