Is such heavy use of backreferencing a declaration from the initialization code covered by at least one of the standards (C99-current) or is it a gcc extension? All the member initialization terms have in common that they either reference the type or a member/variable of that type from within the definition of the type.
#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)
}
I googled around using the searchterms backreferencing declaration from definition, backreferencing declaration from initialization, c initialization struct referencing declaration etc, but all just provide me the differences between declaration and definition. However, i would like to know what is allowed by the standard when i reference the type or a member/variable of that type from within the definition.
In general, you can't refer to struct members from inside the declaration list. For example, this code has undefined behavior:
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
For your specific case though, this does not apply. First of all, the struct definition ends at the }
- from there on it is a complete type, something that has a full definition visible in the current file (pedantically: in the current translation unit).
You then have these cases of initializers:
sizeof(s)
. Since you have a complete type (not a forward-declared struct or a variable-length array etc), using sizeof
is fine. It yields an integer constant expression (C17 6.6/6) and is calculated at compile-time.offsetof
same deal as with sizeof
.&s.offset
and &s
. These are address constants, one type of constant expressions (C17 6.6/7). These are allowed inside an initializer list too and also calculated at compile-time.So all of your initializers are constant expressions - meaning the initializer list is valid. Even if you were to declare this struct with static storage duration.