Why does sizeof(a ? true : false) give an output of four bytes?

I have a small piece of code about the sizeof operator with the ternary operator:

#include <stdio.h>
#include <stdbool.h>

int main()
{
    bool a = true;
    printf("%zun", sizeof(bool));  // Ok
    printf("%zun", sizeof(a));     // Ok
    printf("%zun", sizeof(a ? true : false)); // Why 4?
    return 0;
}

Output (GCC):

1
1
4 // Why 4?

But here,

printf("%zun", sizeof(a ? true : false)); // Why 4?

the ternary operator returns boolean type and sizeof bool type is 1 byte in C.

Then why does sizeof(a ? true : false) give an output of four bytes?


It's because you have #include <stdbool.h> . That header defines macros true and false to be 1 and 0 , so your statement looks like this:

printf("%zun", sizeof(a ? 1 : 0)); // Why 4?

sizeof(int) is 4 on your platform.


Here, ternary operator return boolean type,

OK, there's more to that!

In C, the result of this ternary operation is of type int . [notes below (1,2)]

Hence the result is the same as the expression sizeof(int) , on your platform.


Note 1: Quoting C11 , chapter §7.18, Boolean type and values <stdbool.h>

[....] The remaining three macros are suitable for use in #if preprocessing directives. They are

true

which expands to the integer constant 1,

false

which expands to the integer constant 0, [....]

Note 2: For conditional operator, chapter §6.5.15, (emphasis mine)

The first operand is evaluated; there is a sequence point between its evaluation and the evaluation of the second or third operand (whichever is evaluated). The second operand is evaluated only if the first compares unequal to 0; the third operand is evaluated only if the first compares equal to 0; the result is the value of the second or third operand (whichever is evaluated), [...]

and

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. [....]

hence, the result will be of type integer and because of the value range, the constants are precisely of type int .

That said, a generic advice, int main() should better be int main (void) to be truly standard-conforming.


The ternary operator is a red herring.

    printf("%zun", sizeof(true));

prints 4 (or whatever sizeof(int) is on your platform).

The following assumes that bool is a synonym for char or a similar type of size 1, and int is larger than char .

The reason why sizeof(true) != sizeof(bool) and sizeof(true) == sizeof(int) is simply because true is not an expression of type bool . It's an expression of type int . It is #define d as 1 in stdbool.h .

There are no rvalues of type bool in C at all. Every such rvalue is immediately promoted to int , even when used as an argument to sizeof . Edit: this paragraph is not true, arguments to sizeof don't get promoted to int . This doesn't affect any of the conclusions though.

链接地址: http://www.djcxy.com/p/3586.html

上一篇: C#中字节与字节数据类型的区别

下一篇: 为什么sizeof(a?true:false)给出了四个字节的输出?