通过引用类型或该类型的变量从定义中初始化变量
Initialization of variables from within the definition by referencing the type or a variable of that type
如此大量地使用反向引用来自至少一个标准(C99-current)所涵盖的初始化代码的声明,还是它是 gcc 扩展?
所有成员初始化术语的共同点是它们要么引用类型,要么引用类型定义中该类型的 member/variable。
#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 初始化结构引用declaration 等等,但都只是给我提供了声明和定义之间的区别。但是,我想知道当我从定义中引用类型或该类型的 member/variable 时标准允许的内容。
这里没有什么奇怪的。当我们来到=
时,初始化开始,声明完成。 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};
一般来说,您不能从声明列表中引用结构成员。例如,此代码具有未定义的行为:
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)。这些也允许在初始化列表中并且也在编译时计算。
所以你所有的初始化器都是常量表达式 - 这意味着初始化器列表是有效的。即使你要用静态存储持续时间声明这个结构。
如此大量地使用反向引用来自至少一个标准(C99-current)所涵盖的初始化代码的声明,还是它是 gcc 扩展? 所有成员初始化术语的共同点是它们要么引用类型,要么引用类型定义中该类型的 member/variable。
#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 初始化结构引用declaration 等等,但都只是给我提供了声明和定义之间的区别。但是,我想知道当我从定义中引用类型或该类型的 member/variable 时标准允许的内容。
这里没有什么奇怪的。当我们来到=
时,初始化开始,声明完成。 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};
一般来说,您不能从声明列表中引用结构成员。例如,此代码具有未定义的行为:
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)。这些也允许在初始化列表中并且也在编译时计算。
所以你所有的初始化器都是常量表达式 - 这意味着初始化器列表是有效的。即使你要用静态存储持续时间声明这个结构。