【问题标题】:Why does sizeof(a ? true : false, a) operator printed one byte?为什么 sizeof(a ? true : false, a) 运算符打印一个字节?
【发布时间】:2018-04-14 15:57:24
【问题描述】:

根据this 问题,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):

计算第一个操作数;它之间有一个序列点 评估和第二个或第三个操作数的评估 (以评估为准)。 第二个操作数只有在 首先比较不等于0;仅在以下情况下评估第三个操作数 第一个比较等于 0; 结果是第二个的值 或第三个操作数(以被评估者为准),转换为类型 如下所述。110)

这里,a 是一个bool 类型和赋值true,然后在sizeof 运算符内部,conditional 运算符执行表达式2,因为a 是一个@ 987654337@。

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

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

【问题讨论】:

  • 你用的是什么编译器? gccg++ ?。准确给出你的编译命令
  • @Basile Starynkevitch GCC 编译器。
  • 但是什么编译命令。 gccg++ 的行为不同
  • @BasileStarynkevitch 问题是用 c 标记...
  • 尝试在false,a周围加上括号 --> printf("%zu\n", sizeof(a ? true : (false, a)));,你会得到program - 4的输出。

标签: c boolean sizeof comma conditional-operator


【解决方案1】:

Wiki 中的第一条语句

"在 C 和 C++ 编程语言中,逗号运算符 (由记号 , 表示)是一个二元运算符,它计算其 第一个操作数并丢弃结果"

本质上是这样的

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

评估为

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

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

【讨论】:

  • 引用(来自维基)是残缺不全的,在问题的上下文中没有意义的方式不完整。
【解决方案2】:

首先考虑以下简单的演示程序

#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 宏

bool

扩展为 _Bool。

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

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

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

语法

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 由于整数提升。

【讨论】:

  • sizeof 运算符是否计算括号内的表达式?
  • @surendranath 不,不计算表达式本身。例如,int a = 1; printf("%zu\n", sizeof(++a)); printf("%d\n", a); a 的输出为 1。
  • 那么,sizeof算子怎么打印1呢?是因为_Bool/bool的sizeof还是别的什么?
  • @surendranath 因为表达式的类型为 _Bool,其大小为 1,在演示程序中显示。
  • @surendranath - sizeof 运算符不计算表达式(() 是表达式的一部分)。但是,它确实确定了该表达式结果的类型,即使它实际上并没有计算它。一旦知道结果的类型,它就可以确定该类型的大小。
【解决方案3】:

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

(a ? true : false, a));

Comma operator:

在 C 和 C++ 编程语言中,逗号运算符(由标记 , 表示)是一个二元运算符,它计算第一个操作数并丢弃结果,然后计算第二个操作数并返回此值(和类型)。

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

尝试在false,a 周围加上括号,如下所示:

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

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

【讨论】:

    【解决方案4】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2018-04-11
      • 1970-01-01
      • 2012-05-29
      • 2022-07-05
      • 1970-01-01
      • 1970-01-01
      • 2017-03-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多