我在C中有这个结构,我想初始化为零 . 如何摆脱缺失的括号警告?
typedef struct { uint32_t incoming[FRAME_TYPE_MAX]; uint32_t outgoing[FRAME_TYPE_MAX]; uint32_t timeouts; uint32_t crc_errors; } pkt_t; static pkt_t stats = {0};
这是GCC bug#53119:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119
如果您想要修复它,请在错误报告中发布后续信息,表明这对您来说是个问题 .
由于结构中的第一个成员是您需要的数组:
static pkt_t stats = {{0}};
外部支撑用于结构,内部支撑用于阵列 . 然而,还有许多其他方法可以给这只猫留下皮肤 . (例如,静态已经初始化为零)
如果它是全局变量或本地静态变量,它会自动初始化 . 所以,简单地说:
static pkt_t stats;
一种方法是初始化大括号内结构的每个成员,而不是依赖于隐式零填充 . 对于数组成员,您需要另一个可能导致警告的{} . 另一个是禁用警告,虽然不建议这样做,因为它也可以捕获合法的错误 .
设置此gcc编译器标志:-Wno-missing-braces
来自“info gcc”
作为GNU扩展,GCC允许通过复合文字初始化具有静态存储持续时间的对象(这在ISO C99中是不可能的,因为初始化器不是常量) . 如果复合文字和对象的类型匹配,则处理就像对象仅使用括号括起来的列表初始化一样 . 复合文字的初始化列表必须是常量 . 如果正在初始化的对象具有未知大小的数组类型,则大小由复合文字大小确定 .
static struct foo x = (struct foo) {1, 'a', 'b'}; static int y[] = (int []) {1, 2, 3}; static int z[] = (int [3]) {1};
以上几行等同于以下内容:
static struct foo x = {1, 'a', 'b'}; static int y[] = {1, 2, 3}; static int z[] = {1, 0, 0};
您可以组合这些初始值设定项以允许数组的特定于gcc的初始化,而无需指定数组中的每个元素 . 或者......您可以设置一个标志并在必要时在运行时初始化它,或者......您可以发现变量是否在BSS中并且可以自动归零(这是在函数或全局内存中的堆栈上) ) .
#define FRAME_TYPE_MAX 3 typedef struct { uint32_t incoming[FRAME_TYPE_MAX]; uint32_t outgoing[FRAME_TYPE_MAX]; uint32_t timeouts; uint32_t crc_errors; } pkt_t; static pkt_t stats1= { .incoming={5,6,20}, .outgoing={0,0,0}, .timeouts=0, .crc_errors=0 }; static pkt_t stats2= { {5,6,20}, {0,0,0}, 0, 0 }; static pkt_t stats3= {{0}}; pkt_t stats4 ; // global int main(void) { stats1.incoming[0]= 35; stats1.timeouts=25; stats2.incoming[2]=10; stats3.outgoing[2]=10; stats4.timeouts=10; for (;;); }
如果你仍然对gcc版本感到高兴而省略了这个错误警告,在问题中使用这样的结构你可以通过一些简单的重构来避免这个问题:
typedef struct { uint32_t timeouts; uint32_t crc_errors; uint32_t incoming[FRAME_TYPE_MAX]; uint32_t outgoing[FRAME_TYPE_MAX]; } pkt_t; static pkt_t stats = {0};
8 回答
这是GCC bug#53119:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119
如果您想要修复它,请在错误报告中发布后续信息,表明这对您来说是个问题 .
由于结构中的第一个成员是您需要的数组:
外部支撑用于结构,内部支撑用于阵列 . 然而,还有许多其他方法可以给这只猫留下皮肤 . (例如,静态已经初始化为零)
如果它是全局变量或本地静态变量,它会自动初始化 . 所以,简单地说:
一种方法是初始化大括号内结构的每个成员,而不是依赖于隐式零填充 . 对于数组成员,您需要另一个可能导致警告的{} . 另一个是禁用警告,虽然不建议这样做,因为它也可以捕获合法的错误 .
设置此gcc编译器标志:-Wno-missing-braces
来自“info gcc”
您可以组合这些初始值设定项以允许数组的特定于gcc的初始化,而无需指定数组中的每个元素 . 或者......您可以设置一个标志并在必要时在运行时初始化它,或者......您可以发现变量是否在BSS中并且可以自动归零(这是在函数或全局内存中的堆栈上) ) .
如果你仍然对gcc版本感到高兴而省略了这个错误警告,在问题中使用这样的结构你可以通过一些简单的重构来避免这个问题: