Some Name
Some Name

Reputation: 9521

Self referencing struct declarations

I'm trying to understand what some example in the Standard mean.

N2346::6.7.2.3/p12(emp. mine):

EXAMPLE 2 To illustrate the use of prior declaration of a tag to specify a pair of mutually referential structures, the declarations

struct s1 { struct s2 *s2p; /* ... */ }; // D1
struct s2 { struct s1 *s1p; /* ... */ }; // D2

specify a pair of structures that contain pointers to each other. Note, however, that if s2 were already declared as a tag in an enclosing scope, the declaration D1 would refer to it, not to the tag s2 declared in D2. To eliminate this context sensitivity, the declaration

struct s2;

can be inserted ahead of D1. This declares a new tag s2 in the inner scope; the declaration D2 then completes the specification of the new type.

I don't really understand what the emphasized part means.

If a tag s2 would be declared in the enclosing scope e.g. as follows:

struct s2; //previous visible declaration
struct s1 { struct s2 *s2p; /* ... */ }; // D1
struct s2 { struct s1 *s1p; /* ... */ }; // D2

Then both of the declaration and the definition would specify the same type. N2346::6.7.2.3/p8:

If a type specifier of the form

struct-or-union identifier

or

enum identifier

occurs other than as part of one of the above forms, and a declaration of the identifier as a tag is visible, then it specifies the same type as that other declaration, and does not redeclare the tag.

And the type is the struct s2 { struct s1 *s1p; /* ... */ }; defined at D2.

So what does the Standard by inserting the declaration ahead of D1 to eliminate context sensitivity. I didn't see any context sensetivity here.

Upvotes: 1

Views: 84

Answers (1)

Tom Karzes
Tom Karzes

Reputation: 24052

The example you created only has one scope. To demonstrate the point they're making, you need to have a nested scope. For example, the following complete program demonstrates this:

#include <stdio.h>

struct foo {
    int     a;
};

int main(void)
{
    struct bar {
        int     b;
        struct foo *ptr;
    };

    struct foo {
        int     c;
        struct bar *ptr;
    };

    struct bar x;

    printf("%zu %zu\n", sizeof(struct foo), sizeof(*x.ptr));

    return 0;
}

When I run this on my system, I get:

16 4

The reason these two sizes aren't the same is because the first size is from the local definition of struct foo, while struct bar is using the previously-declared global definition of struct foo, since the definition of struct bar preceded the local definition of struct foo.

Upvotes: 4

Related Questions