c - 通过引用类型或该类型的变量从定义中初始化变量
问题描述
如此大量地使用反向引用来自至少一个标准(C99-current)所涵盖的初始化代码的声明还是它是 gcc 扩展?所有成员初始化术语都有一个共同点,即它们要么引用类型,要么从类型定义中引用该类型的成员/变量。
#include <stddef.h>
#include <stdlib.h>
struct node{
int size;
int offset;
int *ptr;
struct node *this;
} s = {sizeof(s), offsetof(struct node, offset), &s.offset, &s};
int main(void){
struct node *s = malloc(sizeof(*s));
free(s)
}
我搜索了使用 searchterms来自定义的反向引用声明、来自初始化的反向引用声明、c 初始化结构引用声明等,但所有这些都只是为我提供了声明和定义之间的区别。但是,当我从定义中引用类型或该类型的成员/变量时,我想知道标准允许什么。
解决方案
通常,您不能从声明列表中引用结构成员。例如,此代码具有未定义的行为:
typedef struct { int x; int y; } foo_t;
foo_t foo = { .x=5, .y=x }; // BAD, the order of initialization between x and y is not defined
但是,对于您的具体情况,这并不适用。首先,结构定义以}
- 结尾,从那里开始它是一个完整的类型,在当前文件中具有完整的定义可见(迂腐:在当前翻译单元中)。
然后你有这些初始化程序的情况:
sizeof(s)
. 由于您有一个完整的类型(不是前向声明的结构或可变长度数组等),因此使用sizeof
很好。它产生一个整数常量表达式 (C17 6.6/6) 并在编译时计算。offsetof
与 相同的处理sizeof
。&s.offset
和&s
。这些是地址常量,一种常量表达式(C17 6.6/7)。这些也允许在初始化列表中,并且也在编译时计算。
所以你所有的初始化器都是常量表达式——这意味着初始化器列表是有效的。即使您要使用静态存储持续时间声明此结构。
推荐阅读
- redirect - 谁应该设置重定向?
- java - 如何在Android中使用接口作为监听器和Dialoge?
- gstreamer - 'num-buffers' 在 gstreamer 中有什么作用?
- python - 我想从名为scores的txt文件中显示数字的对应字母
- flutter - DatePicker颤动改变显示日期格式
- c# - c#for循环中双变量中的意外数字
- excel - 尝试打印工作表时出现 VBA 宏错误
- python - 在Python中对齐两边的文本
- databricks - 上传后未找到 Databricks DBFS 文件
- android - 如何使用yandex_kit地图实现一些用户的地理定位?