让我对Xcode编译C(gnu11)
感到惊讶#include <stdio.h>
int main(int argc,char**argv)
{
short s = 1;
printf( "%zd %zd %zd\n", sizeof(s), sizeof(s*s), sizeof(s?s:s));
return 0;
}
生成输出
2 4 4
我在期待
2 2 2
或可能
2 4 2
为什么会这样?
答案 0 :(得分:7)
我从K&amp; R回忆起,任何小于int的整数表达式都会被提升为int。我在Standard (C89)中找到了这个:
3.2.1.1字符和整数
char,short int或int位字段,或者它们的签名或 无符号变量,或具有枚举类型的对象,可以是 在任何可以使用int或unsigned int的表达式中使用。如果 int可以表示原始类型的所有值,值为 转换为int;
令人惊讶的是s?s:s因为我能找到的所有引用都说结果类型是左值,但那只是C ++。 C将其视为右值。正如预期的那样,C ++的输出是:
2 4 2
即使表达式是右值。 C和C ++之间出乎意料的差异。
答案 1 :(得分:5)
这是因为后两个sizeof
操作数包含运算符。在C中,在执行操作之前,将比int
更窄的类型提升为int
。因此,s * s
和int
乘以int
,产生int
。
同样,short ? short : short
升级为int ? int : int
。
答案 2 :(得分:4)
根据C11§6.5.15/ 5:
如果第二个和第三个操作数都有算术类型,那么通常的算术转换确定的结果类型是应用于这两个操作数的结果类型,是结果的类型。 [...]
在您的情况下,结果等于sizeof(int)
,因为'usual arithmetic conversions'将short
提升为int
。与sizeof(s*s)
相同。