我刚刚在 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++编译器(虽然不情愿)接受这段代码呢?
$ gcc -Wall array.c array.c:13: warning: missing braces around initializer
- Lucasgcc -Wall
编译时,如果代码中出现if (c = something())
这样的语句,编译器会提示你加上括号,因为它被当做真值使用。仅仅因为某些语句在ANSI C标准下是合法的,并不意味着它们不会产生警告。 - Travis Gockelgcc -std=c89 -pedantic array.c
编译没有警告。 - Lucas