【发布时间】:2017-05-26 13:46:44
【问题描述】:
我有以下结构类型:
typedef struct PG_Point PG_Point;
struct PG_Point
{
int x;
int y;
};
typedef struct PG_Size PG_Size;
struct PG_Size
{
int width;
int height;
};
typedef struct PG_Bounds PG_Bounds;
struct PG_Bounds
{
union
{
struct
{
PG_Point topLeft;
PG_Size size;
};
struct
{
struct
{
int x;
int y;
};
struct
{
int width;
int height;
};
};
};
};
使用以下初始化器:
#define PG_Point_init(ix, iy) {.x=(ix), .y=(iy)}
#define PG_Size_init(iwidth, iheight) {.width=(iwidth), .height=(iheight)}
#define PG_Bounds_init(ix, iy, iwidth, iheight) { \
.topLeft=PG_Point_init((ix),(iy)), \
.size=PG_Size_init((iwidth),(iheight)) }
据我了解,在c11 中初始化匿名结构的字段就像它们是包含结构的直接字段一样正确吗?但是对于 gcc 4.9.2,这会给出以下警告:
警告:'struct
' [-Wmissing-field-initializers] 的字段'size' 缺少初始化程序
如果我将初始化程序更改为这个版本,它会起作用:
#define PG_Bounds_init(ix, iy, iwidth, iheight) {{{ \
.topLeft=PG_Point_init((ix),(iy)), \
.size=PG_Size_init((iwidth),(iheight)) }}}
也就是说,明确地将联合和结构作为子聚合。
这甚至允许吗?我是否必须期望其他编译器拒绝这个?
【问题讨论】:
-
尝试用
-pedantic编译。如果它没有给你警告,你应该很高兴。 -
是的,我已经这样做了,clang 3.5.0 和 gcc 6.3.0 没有什么可抱怨的。阅读this answer的标准引号后仍然不确定是否允许
-
编译器并没有拒绝它——它只是发出了一个警告。你应该认真对待这一点,但这可能不是问题。编写一个简短的测试程序来检查对象是否按预期初始化怎么样?
-
@JohnBollinger 好主意,也许 gcc 4.9 实际上做“正确的事情”......我会尝试。
-
FWIW,在 C11 模式下编译时,gcc 4.8.5 仅在启用
-Wextra时才会发出该警告。
标签: c11 c gcc language-lawyer c11