Bel*_*now 19 c unsigned signed ternary-operator conditional-operator
我认为((1 ? (int)1 : (unsigned int)2) > -1)结果是1(true),但实际上它0在Visual Studio 2017中是(假的).
我认为价值(1 ? (int)1 : (unsigned int)2)应该是(int)1,因为1 ?是真的,而且1 > -1是真的.
我不知道为什么这个表达式的最终结果是错误的.
当我尝试转换时((int)(1 ? (int)1 : (unsigned int)2) > -1),它返回1(true).
signed int test = -1;
signed int si = 1;
unsigned int ui = 2;
printf("%d\n", ((1 ? si : ui) > test));
return 0;
Run Code Online (Sandbox Code Playgroud)
我希望输出是1,但实际输出是0.
Eri*_*hil 20
类型a ? b : c不依赖于a.它的类型b和无条件地决定c.完整规则很复杂,但是,对于算术操作数,类型由通常的算术转换确定.实际上,两个操作数被转换为通用类型.对于int和unsigned int,结果类型是unsigned int.
条件运算符? :在C 2018标准的第6.5.15节中描述.第4段说结果"转换为下面描述的类型."
第5段描述了算术类型,结构和联合的结果:
如果第二个和第三个操作数都具有算术类型,那么通常的算术转换确定的结果类型是应用于这两个操作数的结果类型.如果两个操作数都具有结构或联合类型,则结果具有该类型.如果两个操作数都具有void类型,则结果为void类型.
算术类型是整数和浮点类型,每6.2.5 18.(包括实数和复数类型.)通常的算术转换在6.3.1.8 1中描述,它们(在我的摘要中,未引用):
long double,结果是long double.double,结果是double.float,结果是float.int或更窄(意味着更少的位或相同的数量)比特但签名而不是无符号),结果是int.否则,如果两者都是unsigned int或更窄,结果是unsigned int.否则,结果是更宽的类型.结构,联合和void规则是明确的:两个操作数必须具有相同的类型,这就是结果.
第6段描述了指针的结果:
如果第二个和第三个操作数都是指针,或者一个是空指针常量而另一个是指针,则结果类型是指向使用两个操作数引用的类型的所有类型限定符限定的类型的指针.此外,如果两个操作数都是兼容类型的指针或兼容类型的不同限定版本,则结果类型是指向复合类型的适当限定版本的指针; 如果一个操作数是空指针常量,则结果具有另一个操作数的类型; 否则,一个操作数是一个指向无效或有资格版本的空隙,在这种情况下,结果类型是一个指向的一个适当资格版本空隙.
总之,这说:
const,volatile,restrict,或_Atomic),包括那些在结果类型.