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

后端 未结 7 1418
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-30 07:41

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

#include 
#include 

int main()
{
         


        
7条回答
  •  爱一瞬间的悲伤
    2021-01-30 08:16

    Regarding the boolean type in C

    A boolean type was introduced fairly late in the C language, in the year 1999. Before then, C did not have a boolean type but instead used int for all boolean expressions. Therefore all logical operators such as > == ! etc return an int of value 1 or 0.

    It was custom for applications to use home-made types such as typedef enum { FALSE, TRUE } BOOL;, which also boils down to int-sized types.

    C++ had a much better, and explicit boolean type, bool, which was no larger than 1 byte. While the boolean types or expressions in C would end up as 4 bytes in the worst case. Some manner of compatibility with C++ was introduced in C with the C99 standard. C then got a boolean type _Bool and also the header stdbool.h.

    stdbool.h provides some compatibility with C++. This header defines the macro bool (same spelling as C++ keyword) that expands to _Bool, a type which is a small integer type, likely 1 byte large. Similarly, the header provides two macros true and false, same spelling as C++ keywords, but with backward compatibility to older C programs. Therefore true and false expand to 1 and 0 in C and their type is int. These macros are not actually of the boolean type like the corresponding C++ keywords would be.

    Similarly, for backward compatibility purposes, logical operators in C still return an int to this day, even though C nowadays got a boolean type. While in C++, logical operators return a bool. Thus an expression such as sizeof(a == b) will give the size of an int in C, but the size of a bool in C++.

    Regarding the conditional operator ?:

    The conditional operator ?: is a weird operator with a couple of quirks. It is a common mistake to believe that it is 100% equivalent to if() { } else {}. Not quite.

    There is a sequence point between the evaluation of the 1st and the 2nd or 3rd operand. The ?: operator is guaranteed to only evaluate either the 2nd or the 3rd operand, so it can't execute any side-effects of the operand that is not evaluated. Code like true? func1() : func2() will not execute func2(). So far, so good.

    However, there is a special rule stating that the 2nd and 3rd operand must get implicitly type promoted and balanced against each other with the usual arithmetic conversions. (Implicit type promotion rules in C explained here). This means that the 2nd or 3rd operand will always be at least as large as an int.

    So it doesn't matter that true and false happen to be of type int in C because the expression would always give at least the size of an int no matter.

    Even if you would rewrite the expression to sizeof(a ? (bool)true : (bool)false) it would still return the size of an int !

    This is because of implicit type promotion through the usual arithmetic conversions.

提交回复
热议问题