您需要稍微更改语法,.main
在初始化程序中初始化instance
:
typedef struct MainStruct {
union {
uint8_t a8[16];
uint64_t a64[2];
};
uint64_t i64;
} MainStruct_t;
typedef struct OtherStruct {
MainStruct_t main;
int otherval;
} OtherStruct_t;
OtherStruct_t instance = { .main = {.a64 = { 0, 0 }}, .otherval = 3 };
这是一个工作测试程序:
#include <stdio.h>
#include <stdint.h>
typedef struct MainStruct {
union {
uint8_t a8[16];
uint64_t a64[2];
};
uint64_t i64;
} MainStruct_t;
typedef struct OtherStruct {
MainStruct_t main;
int otherval;
} OtherStruct_t;
OtherStruct_t instance = { .main = {.a64 = { 5, 10 }}, .otherval = 3 };
int main(void)
{
printf("%d, %d\n", (int) instance.main.a64[0], (int) instance.main.a64[1]);
printf("%d\n", instance.otherval);
}
编译后gcc -std=c11 -Wall -Wextra -Wpedantic
,程序输出如下:
5, 10
3
更新
尽管 C99 不支持未命名的结构或联合,但指定初始化程序的这种使用至少也应该适用于 C99。这是一个例子:
#include <stdio.h>
struct Inner {
int x;
int arr[2];
};
struct Outer {
char id[100];
struct Inner state;
};
int main(void)
{
struct Outer instance = { .id = "first",
.state = {.x = 5, .arr[0] = 1, .arr[1] = 2 }};
printf("instance id: %s\n", instance.id);
printf("instance state.x = %d\n", instance.state.x);
printf("instance state.arr[0] = %d\n", instance.state.arr[0]);
printf("instance state.arr[1] = %d\n", instance.state.arr[1]);
return 0;
}
编译后gcc -std=c99 -Wall -Wextra -Wpedantic
,程序输出如下:
instance id: first
instance state.x = 5
instance state.arr[0] = 1
instance state.arr[1] = 2
最后说明
事实证明,OP 的原始语法为:
OtherStruct_t instance = { .main.a64 = { 0, 0 }, .otherval = 3 };
也应该适用于 C99 和 C11,但在不允许初始化子对象的旧标准中不受支持。
C99 不支持未命名的联合,但可以作为 GNU 扩展使用。进一步的调查发现了这个错误报告,它表明未命名结构和联合的指定初始化程序在 gcc 4.6 中已修复。作为解决方法,建议在此链接中将有问题的初始化程序括在大括号中;还提到这种解决方法有点挑剔并且取决于位置,这可以解释为什么它不适用于 OP。