gpt4 book ai didi

c++ - C++ 和 C 中圆括号的含义

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:05:16 24 4
gpt4 key购买 nike

我刚刚在 C++ 中遇到了一个讨厌的错误。所以我有寄存器和值的列表,它们被包装在一个结构中,然后这些结构在一个数组中被初始化。但后来我不小心输入了 () 而不是 {}。这是一些测试代码:

#include <stdio.h>

struct reg_val {
unsigned reg;
unsigned val;
};

struct reg_val faulty_array[] = {
{0x5001, 0xff},
{0x5580, 0x01},
(0x5580, 0x02), //<- THIS LINE IS THE PROBLEM
(0x5589, 0x00), //<- AND THIS LINE
};

struct reg_val good_array[] = {
{0x5001, 0xff},
{0x5580, 0x01},
{0x5580, 0x02},
{0x5589, 0x00},
};

int main()
{
unsigned i;
unsigned faulty_size = sizeof(faulty_array) / sizeof(struct reg_val);
printf("Size of faulty array: %d\n", faulty_size);

for (i = 0; i < faulty_size; ++i) {
printf("faulty reg: %x val: %x\n", faulty_array[i].reg,
faulty_array[i].val);
}

unsigned good_size = sizeof(good_array) / sizeof(struct reg_val);
printf("\nSize of good array: %d\n", good_size);
for (i = 0; i < good_size; ++i) {
printf("good reg: %x val: %x\n", good_array[i].reg,
good_array[i].val);
}
return 0;
}

我对 C 更熟悉,令我惊讶的是这仍然是用 g++ 编译的:

$ g++ -Wall array.cc
array.cc:11: warning: left-hand operand of comma has no effect
array.cc:12: warning: left-hand operand of comma has no effect
array.cc:13: warning: missing braces around initializer for ‘reg_val’
$ ./a.out
Size of faulty array: 3
faulty reg: 5001 val: ff
faulty reg: 5580 val: 1
faulty reg: 2 val: 0 <-- the first value gets discarded as mentioned in the compiler warning

Size of good array: 4
good reg: 5001 val: ff
good reg: 5580 val: 1
good reg: 5580 val: 2
good reg: 5589 val: 0

这段代码显然无法用 C 编译器编译,C++ 中有什么区别使 C++ 编译器(尽管勉强地)接受这段代码?

最佳答案

要回答你的问题,我先回答:为什么这在C中编译失败?好吧,由于以下原因,它无法编译:

initializer element is not constant

为了更好的衡量,让我们从 C 中删除 {}:

struct reg_val faulty_array[] = { 
{0x5001, 0xff},
{0x5580, 0x01},
0x5580, 0x02, //<- THIS LINE IS THE PROBLEM
0x5589, 0x00, //<- AND THIS LINE
};

现在程序输出:

Size of faulty array: 4
faulty reg: 5001 val: ff
faulty reg: 5580 val: 1
faulty reg: 5580 val: 2
faulty reg: 5589 val: 0

这是 C 标准(和 C++)完全允许的。 C(和 C++)展平大括号以初始化结构的元素(这会回来)。您的代码在 C 中失败,因为具有静态存储持续时间的对象必须使用常量表达式或包含常量表达式的聚合初始值设定项进行初始化。 C 不会将 (0x5580, 0x02) 视为常量表达式。

这(不幸地)在 C++ 中编译,因为 C++ 将两个常量表达式之间的逗号运算符视为常量表达式,因此您的代码更像是:

struct reg_val faulty_array[] = { 
{0x5001, 0xff},
{0x5580, 0x01},
0x02,
0x00,
};

...当然,这是允许的。

struct reg_val faulty_array[] = { 
{0x5001, 0xff},
{0x5580, 0x01},
{0x02, 0x00},
};

关于c++ - C++ 和 C 中圆括号的含义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11565023/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com