如何解决通过引用类型或该类型的变量从定义中初始化变量
是否大量使用了至少一个标准(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)
}
我使用搜索词搜索了定义中的反向引用声明、初始化中的反向引用声明、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
不过,对于您的具体情况,这并不适用。首先,结构体定义以 }
结束 - 从那里开始它是一个 complete 类型,在当前文件中具有完整定义的东西(迂腐:在当前翻译中单位)。
然后你有这些初始化器的情况:
-
sizeof(s)
。由于您有一个完整的类型(不是前向声明的结构或可变长度数组等),因此使用sizeof
很好。它产生一个整数常量表达式 (C17 6.6/6) 并在编译时计算。 -
offsetof
与sizeof
的交易相同。 -
&s.offset
和&s
。这些是地址常量,一种类型的常量表达式 (C17 6.6/7)。这些也允许在初始值设定项列表中,并且也在编译时计算。
所以你所有的初始化器都是常量表达式——这意味着初始化器列表是有效的。即使您要使用静态存储持续时间声明此结构。
,这里没有什么奇怪的。当我们来到 =
时,初始化开始,声明完成。 sizeof
运算符需要一个完整的类型,即您的结构体。例如,这不起作用:
struct x;
int n = sizeof x;
此外,就您而言,您不仅拥有完整的类型。您还声明了一个对象 s
。正因为如此,&s.offset
和 &s
都是完全有效的。
在某些情况下,反向引用不起作用。这是一个:
int x[] = { sizeof x };
产生此错误:
error: invalid application of ‘sizeof’ to incomplete type ‘int[]’
2 | int x[] = {sizeof x};
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。