sizeof C中的整数表达式

用Xcode编译C(gnu11)让我半惊喜

#include  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因为我能找到的所有引用都说结果类型是左值,但那只是C ++。 C将其视为右值。 正如预期的那样,C ++的输出是:

 2 4 2 

即使表达式是右值。 C和C ++之间出乎意料的差异。

这是因为后两个sizeof操作数包含运算符 。 在C中,在执行操作之前,将比int更窄的类型提升为int 。 所以s * sint乘以一个int ,得到一个int

同样short ? short : short short ? short : short升级到int ? int : int int ? int : int

根据C11§6.5.15/ 5:

如果第二个和第三个操作数都具有算术类型,那么通常算术转换确定的结果类型是应用于这两个操作数的结果类型。 […]

在您的情况下,结果等于sizeof(int)因为’通常的算术转换’将short s提升为int 。 与sizeof(s*s)