Search code examples
cgcccircular-referencestatic-initializationrecursive-datastructures

Initializing circular data in C. Is this valid C code according to any standard?


I wanted to see if I could initialize a global variable to point to itself:

#include <stdio.h>
struct foo { struct foo *a, *b; } x = { &x, &x };
int main()
{
    printf("&x = %p, x.a = %p, x.b = %p\n", &x, x.a, x.b);
    return 0;
}

This code compiles and runs as expected with gcc (all three pointers print identically).

I want to know:

  1. Is this reliable?
  2. Is this standard?
  3. Is this portable?

EDIT: Just to clarify, I am questioning the availability of the address of x in its own initializer.


Solution

  • This is standard C code.

    This paragraph of the mighty Standard permits it (emphasis mine):

    (C99, 6.2.1p7) "Structure, union, and enumeration tags have scope that begins just after the appearance of the tag in a type specifier that declares the tag. Each enumeration constant has scope that begins just after the appearance of its defining enumerator in an enumerator list. Any other identifier has scope that begins just after the completion of its declarator."

    For information, note that to illustrate the last sentence of 6.2.1p7, the book "The New C Standard" by Derek M. Jones uses an example similar to yours:

    struct T {struct T *m;} x = /* declarator complete here. */ {&x};