为什么指向未定义结构的指针有时在 C 和 C++ 中是非法的
为什么
void foo(T*);
在 C 和 C++ 中都是非法的(因为 T
未定义),而在T
中却
void foo(struct T*);
是有效的,即使它仍然没有定义T
?在任何情况下,无论 T
是结构体还是其他类型(类/枚举/typedef/等),它都会对调用者产生语义差异吗?
Why is
void foo(T*);
illegal in both C and C++ (because T
is undefined), whereas
void foo(struct T*);
is valid, even though it still does not define T
? Is there any situation in which it makes a semantic difference to the caller whether T
is a struct or some other type (class/enum/typedef/etc.)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在 C 中,因为指向结构(任何结构)的指针都具有相同的宽度和对齐属性
另一方面,指向任何内容的指针可能具有不同的宽度和/或对齐属性(void*、函数指针、unsigned char* 等)
In C, because pointer to structs (any struct) all have the same width and alignment properties
Pointers to anything, on the other hand, may have distinct width and/or alignment properties (void*, function pointers, unsigned char*, ...)
void foo(struct T*);
同时充当该范围内struct T
的前向声明,因此可以安全地命名指向它的指针。在
void foo(T*)
中,没有告诉T
应该是什么。如果结果是变量的名称而不是类型,则该代码行格式错误。 C++ 需要更多信息才能确定该代码行有效。void foo(struct T*);
simultaneously functions as a forward-declaration ofstruct T
within that scope, so it's safe to name a pointer to it.In
void foo(T*)
there is no telling whatT
is supposed to be. If it turns out to be the name of a variable rather than a type, then the line of code is ill-formed. C++ needs more information before it can say that the line of code is valid.充当 T 的前向声明。您向编译器承诺稍后将定义它。如果你实际上在 T 上做了一些事情或者尝试实例化它,你就会遇到问题:
Just
是一个任意标识符。它是一个变量吗?它是一个函数吗?该语言不提供在变量前面添加
struct
或class
来转发声明的功能。acts as a forward declaration of T. You're promising the compiler you'll define it later. If you actually did something on T or tried to instantiate it, you'd have problems:
Just
is an arbitrary identifier. Is it a variable? Is it a function? The language provides no facility to forward declare without adding
struct
orclass
in front of the variable.struct T
将T
声明为struct
,即使它出现在较大的声明中,即foo
的声明。该类型不完整,但当它用于声明指针函数参数时,这并不重要。如果没有
struct
,编译器就不知道T
应该是什么。如果
T
之前已声明为struct
,则在 C++ 中允许使用void foo(T*)
,但在 C 中则不允许,因为的名称code>struct
不会自动成为类型名称,尽管您可以根据需要在 C 中声明具有相同名称的typedef
。struct T
declaresT
as astruct
even when it appears in a larger declaration, i.e. the declaration offoo
. The type is incomplete but that doesn't matter when it's used to declarat a pointer function parameter.Without the
struct
the compiler doesn't know anything about whatT
is supposed to be.If
T
had previously been declared as astruct
thenvoid foo(T*)
would be allowed in C++ but not C because the names ofstruct
s don't automatically become type names although you can declared atypedef
with an identical name in C if you want to.