对于使用 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
为什么会这样呢?
对于使用 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
为什么会这样呢?
我从K&R中回想起任何小于int的整数表达式都会被提升为int。 我在标准(C89)中找到了这一点:
3.2.1.1 字符和整数
char、short int或int位域,它们的有符号或无符号变体或具有枚举类型的对象都可以在表达式中使用,无论何时都可以使用 int 或 unsigned int。如果int可以表示原始类型的所有值,则将该值转换为int;
令人惊讶的是s?s:s,因为我找到的所有参考资料都说结果类型是lvalue,但这只适用于C ++。 C将其视为rvalue。 然后,C ++的输出如下所示:
2 4 2
sizeof
操作数包含运算符。在C语言中,比int
窄的类型在执行操作之前会被提升为int
。因此,s * s
是一个int
乘以一个int
,得到一个int
。short ? short : short
也会被提升为int ? int : int
。在您的情况下,结果等于如果第二个和第三个操作数都是算术类型,那么将这两个操作数应用于通常的算术转换所确定的结果类型就是结果的类型。[...]
sizeof(int)
,因为“通常的算术转换”会将short
提升为int
。与sizeof(s*s)
相同。
sizeof
运算符时可见:在C中,printf("%zd\n", sizeof('s'));
可能会打印出4
,但在C++中始终为1
。 - chqrlie