问题
To my semi-surprise with Xcode compiling 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;
}
Produces the output
2 4 4
I was expecting
2 2 2
or possibly
2 4 2
Why is this?
回答1:
I recalled from K&R that any integer expression smaller than an int is promoted to int. I found this in Standard (C89):
3.2.1.1 Characters and integers
A char, a short int, or an int bit-field, or their signed or unsigned varieties, or an object that has enumeration type, may be used in an expression wherever an int or unsigned int may be used. If an int can represent all values of the original type, the value is converted to an int;
The surprise is s?s:s because all reference I could find say the resulting type is an lvalue but that's just C++. C treats it as an rvalue. As expected then, C++'s output is:
2 4 2
Even if the expression is an rvalue. An unexpected difference between C and C++.
回答2:
This is because the latter two sizeof
operands contain operators. In C, types narrower than int
are promoted to int
before the operation is performed. So s * s
is and int
multiplied with an int
, yielding an int
.
Similarly for short ? short : short
getting promoted to int ? int : int
.
回答3:
According to C11§6.5.15/5:
If both the second and third operands have arithmetic type, the result type that would be determined by the usual arithmetic conversions, were they applied to those two operands, is the type of the result. [...]
In your case, the result is equal to sizeof(int)
because the 'usual arithmetic conversions' promote the short
s to int
s. Same as with sizeof(s*s)
.
来源:https://stackoverflow.com/questions/33068985/sizeof-an-integer-expression-in-c