C 中 sizeof() 运算符中 "comma" 运算符的行为

Behavior of "comma" operator in sizeof() operator In C

我写了关于 sizeof 运算符的代码。如果我这样写:

#include <stdio.h>

int main() {
    char a[20];
    printf("%zu\n", sizeof(a));
    return 0;
}

输出:

20 // Ok, it's fine

但是,如果我像这样使用 逗号 运算符:

#include <stdio.h>

int main() {
    char a[20];
    char b;
    printf("%zu\n", sizeof(b, a));
    return 0;
}

输出:

8 // Why the output 8?

所以,我有一个问题:

在大多数情况下,数组会退化为指针。因此,带有逗号运算符的 b,a 的类型是 char*(不再是 char[20])。指针在你的机器上是 8 个字节。

顺便说一句,我认为在某些逗号运算符上使用 sizeof 确实会使 reader 混淆。我建议在简单表达式或类型上使用 sizeof

(我刚刚发现这是 C 和 C++ 之间的棘手差异之一;参见 this explanation

逗号运算符对sizeof没有特殊意义。

sizeof(b, a) 检查完整的表达式 (b, a),计算结果类型,并计算该类型的大小而不实际计算 (b , a)。正如 chqrlie 在评论中指出的那样,() 是计算(结果的)大小的表达式的一部分。

在这种情况下,b 是一个 chara 是一个数组。如果要计算表达式 b, a,则将首先计算 b,然后丢弃结果。然后 a 将转换为值等于 &a[0] 的指针 (char *),这将是表达式 (b, a).

的结果

由于 b, a 的结果属于 char * 类型,因此 sizeof(b,a) 等于 sizeof (char *)。这是一个实现定义的值,但对于您的编译器而言,它的值为 8(这可能意味着代码被构建为 64 位应用程序)。

sizeof 由其操作数的类型决定大小。在 sizeof(a) 中,a 不会衰减到指向其第一个元素的指针,并且 a 的类型将为 char[20]。在 sizeof(b, a) 中,a 是逗号运算符的右操作数,在这种情况下,它将衰减为指向它的第一个元素的指针,表达式 b , a 的类型将是 char *.因此,sizeof(b, a) 将 return 大小的 char * 数据类型。

在 C++ 中,, 运算符的结果是一个左值(不同于在 C 中它产生一个右值)。在那种情况下 sizeof(b, a) 将 return 数组的大小 a.

C 语言是一种左值丢弃 语言。 C 中的逗号运算符不产生左值,也不保留数组的 "arrayness"。这意味着当右侧操作数是一个数组时,它会立即进行数组到指针的转换。由于这个原因,在 C 中,逗号运算符的结果是 char * 类型的右值。这就是您应用 sizeof 的对象。这就是为什么你得到 8 结果,这是你平台上的指针大小。

C++ 语言是一种左值保留 语言。 C++ 中逗号运算符的右手操作数是 not 进行左值到右值转换,如果操作数是数组,它会保持其左值性和数组类型。在 C++ 中,逗号运算符的结果是 char[20] 类型的左值。这就是您应用 sizeof 的对象。这就是为什么你得到 20 作为结果。