为什么 sizeof(a ? true : false, a) 运算符打印一个字节?

Why does sizeof(a ? true : false, a) operator printed one byte?

根据 问题,sizeof(true)sizeof(false)4 字节,因为 truefalse 是宏并在 #include <stdbool.h> 头文件.

但是,这里是有趣的程序输出。

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

int main() 
{
    bool a = true;
    printf("%zu\n", sizeof(a ? true : false, a));
                             /* ^^ -> expresion2 */
    return 0;
}

输出(Live demo):

1

C11 6.5.15 条件运算符(P4):

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), converted to the type described below.110)

这里,a是一个bool类型,赋值true,那么在sizeof运算符内部,conditional运算符执行了expression2 因为 a 是一个 true

所以,comma operator part(expression3) 没有按照标准求值,expression2 是一个宏。所以,根据那个问题,宏的输出是 4 字节,但在这里,程序的输出是 1 字节。

所以在这里,为什么 sizeof(a ? true : false, a) 只打印 1 字节?

a ? true : false, a 是两个表达式,用逗号分隔。它丢弃三元运算符的结果并简单地评估为 a.

因为 abool,在 stdbool.h 中是 _Bool 的宏,所以您打印 _Bool 数据类型的大小。 _Bool 很可能只是一个字节,因为它只需要保存值 1 和 0。

为了与链接的问题进行对比,您打印了 truefalsestdbool.h 定义为 1 和 0 的预处理器宏。这两个是 int 常量,因此它们的大小是 int 数据类型的大小。

由于表达式中使用了逗号运算符,您得到 1

(a ? true : false, a));

Comma operator:

In the C and C++ programming languages, the comma operator (represented by the token ,) is a binary operator that evaluates its first operand and discards the result, and then evaluates the second operand and returns this value (and type).

因此,在表达式 (a ? true : false, a)); 中,由于逗号运算符,三元运算符的结果被丢弃,然后它计算第二个操作数和 return a。由于 abool 类型,因此您的程序输出为 sizeof(bool),即 1.

试着把 false,a 括起来,像这样:

printf("%zu\n", sizeof(a ? true : (false, a)));

当您将表达式 false, a 放在方括号 () 中时,表达式 (false, a) 将首先被计算,逗号运算符 returns a 但三元运算符将计算表达式 return true,这是一个扩展为整数常量 1 的宏,程序的输出将是 sizeof(1)4

对于初学者来说,请考虑以下简单的演示程序

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

int main(void) 
{
    printf( "sizeof( _Bool ) = %zu\n", sizeof( _Bool ) );
    printf( "sizeof( bool )  = %zu\n", sizeof( bool ) );

    return 0;
}

它的输出是

sizeof( _Bool ) = 1
sizeof( bool ) = 1

根据 C 标准(7.18 布尔类型和值)

2 The macro

bool

expands to _Bool.

现在让我们考虑一下此调用中 sizeof 运算符中使用的表达式

printf("%zu\n", sizeof(a ? true : false, a));

根据 C 标准(6.5.15 条件运算符)

Syntax

1 conditional-expression:
    logical-OR-expression
    logical-OR-expression ? expression : conditional-expression

即条件运算符的优先级高于逗号运算符

所以这个表达式

a ? true : false, a

是带逗号运算符的表达式,可以等价改写为

( a ? true : false ) , ( a )

表达式的结果是逗号运算符的第二个操作数,即表达式 ( a )

如上所示,此表达式的类型为 _Bool,因为变量 a 的声明方式类似于

bool a = true;

其中宏 bool 扩展为 _Bool。所以 sizeof( _Bool ) 等于 1.

如果您将按此调用中所示的以下方式重写条件运算符

printf( "%zu\n", sizeof( a ? true : a ) );

那么输出将等于 sizeof( int ) 返回的值(通常等于 4),因为类型 _Bool 的等级低于类型 int (扩展宏 true 的常数整数文字的类型),结果表达式 a 由于整数提升将隐式转换为类型 int

Wiki

中的第一个语句

"In the C and C++ programming languages, the comma operator (represented by the token ,) is a binary operator that evaluates its first operand and discards the result"

所以基本上

printf("%zu\n", sizeof(a ? true : false, a));

评估为

printf("%zu\n", sizeof(a));

a 是 bool 类型,rest 是你得到的输出。