Reputation: 136
Having the following C code:
struct Point2_s;
struct Point1_s{
int x;
int y;
Point2_s P2;
} Point1;
struct Point2_s{
int x;
int y;
} ;
int main() {
...
return 0;
}
I'm getting an error:
unknown type name ‘Point2_s’
Can anyone can please explain me WHY it doesn't work? Why doesn't the struct Point2_s
declaration is insufficient when defining the Point1_s
member P2
?
Upvotes: 1
Views: 116
Reputation: 311126
In this line
struct Point2_s;
there is declared an incomplete structure specifier struct Point2_s
.
In this declaration
struct Point1_s{
int x;
int y;
Point2_s P2;
} Point1;
there is used an unknown name Point2_s
. It is not the same as struct Point2_s
.
But even if you will write
struct Point1_s{
int x;
int y;
struct Point2_s P2;
} Point1;
nevertheless you may not use an incomplete type in a data member declaration.
From the C Standard (6.7.2.1 Structure and union specifiers)
3 A structure or union shall not contain a member with incomplete or function type (hence, a structure shall not contain an instance of itself, but may contain a pointer to an instance of itself), except that the last member of a structure with more than one named member may have incomplete array type; such a structure (and any union containing, possibly recursively, a member that is such a structure) shall not be a member of a structure or an element of an array.
Instead you need to write
struct Point2_s{
int x;
int y;
} ;
struct Point1_s{
int x;
int y;
struct Point2_s P2;
} Point1;
Or you could write
typedef struct Point2_s{
int x;
int y;
} Point2_s;
struct Point1_s{
int x;
int y;
Point2_s P2;
} Point1;
In this case the name Point2_s
is an alias for the type specifier struct Point2_s
.
On the other hand, as it is pointed out in other answers you may use pointers to incomplete types because pointers themselves are always complete types. That is you may write
struct Point2_s;
struct Point1_s{
int x;
int y;
struct Point2_s *P2;
} Point1;
Upvotes: 2
Reputation: 68034
Forward declaration will not work in this case (abstracting from missing struct
) as compiler needs to know the size of the member P2
. You need to declare it before the the declaration which uses it.
struct Point2_s{
int x;
int y;
} ;
struct Point1_s{
int x;
int y;
struct Point2_s P2;
} Point1;
Forward declaration will only work only for pointers:
struct Point2_s;
struct Point1_s{
int x;
int y;
struct Point2_s *P2;
} Point1;
struct Point2_s{
int x;
int y;
} ;
Upvotes: 0
Reputation: 155684
A forward declaration can only be used to declare pointers to the forward-declared struct. It doesn't know how big it is though, so it can't use the type directly (how does it know how much space to reserve for the P2
member?).
Just reverse the order of declaration:
struct Point2_s{
int x;
int y;
};
struct Point1_s{
int x;
int y;
struct Point2_s P2; // You didn't typedef, so by the C standard, you need struct to declare the member
} Point1;
or you'll need to use pointers:
struct Point2_s;
struct Point1_s{
int x;
int y;
struct Point2_s *P2; // Pointer, again adding struct; P2 will need to be allocated separately, e.g. by malloc
} Point1;
struct Point2_s{
int x;
int y;
};
Upvotes: 2