英文:
Struct declaration NOT sufficient?
问题
以下是翻译好的部分:
在以下的C代码中:
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;
}
我得到了一个错误:
未知类型名‘Point2_s’
有人能解释为什么它不工作吗?为什么在定义Point1_s
成员P2
时Point2_s
结构体的声明不足呢?
英文:
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
?
答案1
得分: 2
在这行中,声明了一个不完整的结构体指定符 struct Point2_s
。
在这个声明中,使用了一个未知的名称 Point2_s
。它与 struct Point2_s
不同。
但即使你写成:
struct Point1_s{
int x;
int y;
struct Point2_s P2;
} Point1;
你仍然不能在数据成员声明中使用不完整的类型。
根据C标准(6.7.2.1 结构和联合体指定符):
3 结构体或联合体不得包含不完整或函数类型的成员(因此,结构体不得包含自身的实例,但可以包含指向自身实例的指针),除非具有多个命名成员的结构体的最后一个成员具有不完整的数组类型;这样的结构体(以及包含该结构体成员的任何联合体,可能递归地包含该结构体成员)不得作为结构体的成员或数组的元素。
因此,你需要这样写:
struct Point2_s{
int x;
int y;
} ;
struct Point1_s{
int x;
int y;
struct Point2_s P2;
} Point1;
或者你可以这样写:
typedef struct Point2_s{
int x;
int y;
} Point2_s;
struct Point1_s{
int x;
int y;
Point2_s P2;
} Point1;
在这种情况下,名称 Point2_s
是类型说明符 struct Point2_s
的别名。
另一方面,正如其他回答中指出的,你可以使用不完整类型的指针,因为指针本身始终是完整类型。也就是说,你可以这样写:
struct Point2_s;
struct Point1_s{
int x;
int y;
struct Point2_s *P2;
} Point1;
英文:
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;
答案2
得分: 2
前向声明仅用于声明前向声明的结构体的指针。但它不知道结构的大小,因此不能直接使用该类型(它如何知道为 P2
成员保留多少空间?)。
只需颠倒声明的顺序:
struct Point2_s{
int x;
int y;
};
struct Point1_s{
int x;
int y;
struct Point2_s P2; // 没有使用 typedef,所以按照 C 标准,需要使用 struct 声明成员
} Point1;
或者你需要使用指针:
struct Point2_s;
struct Point1_s{
int x;
int y;
struct Point2_s *P2; // 指针,再次添加 struct;P2 需要单独分配空间,例如使用 malloc
} Point1;
struct Point2_s{
int x;
int y;
};
英文:
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;
};
答案3
得分: 0
前向声明在这种情况下不起作用(抽象出缺少的“struct”),因为编译器需要知道成员“P2”的大小。您需要在使用它的声明之前进行声明。
struct Point2_s{
int x;
int y;
} ;
struct Point1_s{
int x;
int y;
struct Point2_s P2;
} Point1;
前向声明仅适用于指针:
struct Point2_s;
struct Point1_s{
int x;
int y;
struct Point2_s *P2;
} Point1;
struct Point2_s{
int x;
int y;
} ;
英文:
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;
} ;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论