使用具有未命名嵌套数据类型的指定初始化程序 [英] Using designated initializers with unnamed nested data types
问题描述
我想知道是否可以在结构的未命名数据成员中使用指定的初始值设定项...(Yikes,一口一口,但是,是的,这是最干净的方式来做我想做的事情...... )。如果我有:
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};
我试着编译,出现错误:
tst3.c:16:error:初始化程序中指定的未知字段'a64'
我也尝试过使用 .main..a64
,但我遇到了其他问题。这是与gcc 4.4。不幸的是,整个代码都使用 MainStruct
,所以命名union会涉及到更改数百个文件,所以我想避免这种情况。如果可能的话,我还想在 OtherStruct
内避免任何关于 MainStruct
位置的假设。
您需要稍微更改语法,在初始化程序中为<$初始化 .main
$ b $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ b 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\\\
,instance.otherval);
$ b
用编译gcc -std = c11-Wall -Wextra -Wantantic
,这里是程序输出:
5,10
3
更新
指定的初始值设定项也应该至少与C99一起工作,尽管C99不支持未命名的结构或联合。这里是一个例子:
#include
struct Inner {
int x;
int arr [2];
};
struct Outer {
char id [100];
struct内部状态;
};
int main(void)
{
struct Outer instance = {.id =first,
.state = {.x = 5,.arr [ 0] = 1,.arr [1] = 2}};
printf(instance id:%s\\\
,instance.id);
printf(instance state.x =%d \ n,instance.state.x);
printf(instance state.arr [0] =%d \\\
,instance.state.arr [0]);
printf(instance state.arr [1] =%d \\\
,instance.state.arr [1]);
返回0;
}
用编译gcc -std = c99 -Wall -
实例ID:第一个
实例state.x = 5
instance state.arr [0] = 1
instance state.arr [1] = 2
Final Note
事实证明,OP的原始语法为:
OtherStruct_t instance = {.main.a64 = {0,0},.otherval = 3};
也可以在C99和C11上工作,但在不允许初始化的旧标准中不受支持的子对象。
I'm wondering if it is possible to use designated initializers in unnamed data members of structs... (Yikes, a mouthful, but yes, it is the cleanest way to do what I'm trying to do...). If I have:
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 };
and I try to compile, I get the error:
tst3.c:16: error: unknown field ‘a64’ specified in initializer
I've also tried using .main..a64
, but I'm getting other issues. This is with gcc 4.4. Unfortunately, the MainStruct
is used all over the code, so naming the union would involve changing hundreds of files, so I'd like to avoid that. I'd also like to avoid any assumptions about position of MainStruct
within OtherStruct
if possible.
You need to change the syntax a bit, initializing .main
within the initializer for 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 };
Here is a working test program:
#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);
}
Compiled with gcc -std=c11 -Wall -Wextra -Wpedantic
, here is the program output:
5, 10
3
Update
This use of designated initializers should also work with at least C99, though C99 does not support unnamed structures or unions. Here is an example:
#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;
}
Compiled with gcc -std=c99 -Wall -Wextra -Wpedantic
, here is the program output:
instance id: first
instance state.x = 5
instance state.arr[0] = 1
instance state.arr[1] = 2
Final Note
It turns out that OP's original syntax of:
OtherStruct_t instance = { .main.a64 = { 0, 0 }, .otherval = 3 };
should also work on both C99 and C11, but is not supported in older standards which do not allow initialization of subobjects.
Unnamed unions are not supported in C99, but are available as a GNU extension. Further investigation has turned up this bug report which suggests that designated initializers for unnamed structs and unions were fixed in gcc 4.6. As workaround, it was suggested at this link to enclose the offending initializer in braces; it is also mentioned that this workaround is a bit finicky and position dependent, which may explain why it does not work here for OP.
这篇关于使用具有未命名嵌套数据类型的指定初始化程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!