前向 typedef 结构
gcc 4.4.4 c89
我的头文件中有这个。
port.h
struct struct_tag;
int initialize_ports(struct_tag *port);
在我的实现文件中,我有这个:
port.c
typedef struct struct_tag {
int port_id;
} Port_t;
在我的 driver.h 文件中,我有以下内容:
#include "port.h"
int initialize_ports(struct_tag *port)
{
port = malloc(sizeof *port);
/* do checking here */
}
我已经向前声明了结构,因为我想隐藏内部元素。
但是,我在头文件中的initialize_ports上收到以下错误:
expected ‘)’ before ‘*’ token
我只是想知道如何转发声明并能够将结构作为参数传递?
非常感谢您的任何建议,
gcc 4.4.4 c89
I have this in my header file.
port.h
struct struct_tag;
int initialize_ports(struct_tag *port);
In my implemenation file I have this:
port.c
typedef struct struct_tag {
int port_id;
} Port_t;
And in my driver.h file, I have the following:
#include "port.h"
int initialize_ports(struct_tag *port)
{
port = malloc(sizeof *port);
/* do checking here */
}
I have forward declared the structure, as I want to hide the internal elements.
However, I am getting the following error on my initialize_ports in the header file:
expected ‘)’ before ‘*’ token
I am just wondering how can I forward declare and be able to pass the structure as a parameter?
Many thanks for any advice,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您应该使用:
此外,前向声明会给您一个您不知道其大小的不完整类型。如果您需要分配一个
struct struct_tag
,您需要包含它的完整定义。或者,如果您想使其完全不透明,您可以使用一些create_struct_tag()
函数。You should use:
Also, forward declarations give you an incomplete type which you don't know the size of. If you need to allocate a
struct struct_tag
you need to include the full definition for it. Alternatively you could use somecreate_struct_tag()
function if you want to make it fully opaque.正如其他答案所指出的,您可以在原型中将
struct_tag
更改为struct struct_tag
。编译代码的另一种方法是代替现有的 struct struct_tag; 进行编写(即将 typedef 与前向定义结合起来)。这样您就可以
在没有编译失败的情况下进行编写。然而,这仍然不是您想要的,因为调用者既不能分配这种类型的局部变量,也不能分配 malloc() 变量 - 因为他们不知道大小。
其他答案建议您应该开放结构的定义。这通常不是正确的答案 - 因为它删除了您尝试创建的抽象层。最好有函数(在
port.c
中,即确实了解内部结构的库),例如:即创建和释放结构 - 实际上是为了其他操作(例如读取/写入结构)也是如此。
As other answers have noted, you could change
struct_tag
tostruct struct_tag
in the prototype. Another way of getting your code to compile is to writein place of your existing
struct struct_tag;
(i.e. combine the typedef with the forward definition). That then does allow you to writewithout compile failures. However, this is still not quite what you want, because the caller can neither allocate a local variable of this type, nor malloc() one - because they don't know the size.
Other answers have suggested that you should open up the definition of the structure. That's generally not the right answer - because it removes the abstraction layer you're trying to create. Much better to have functions (in the
port.c
, i.e. the library that does know about the internals) such as:i.e. to create and free the structures - and indeed for other operations (such as reading from / writing to the structure) too.
您会收到错误,因为您不知道“端口”的大小,因为它所要做的只是前向声明。
总之,您最好不要在这里使用前向声明,除非您还设置了一个常量值,即“struct_tag”的大小……您很可能最好完全声明它。
You'll get an error as you don't KNOW the size of "port" as all it has to go on is the forward declaration.
In summary you are best off not using a forward declaration here unless you also set a constant value that is the sizeof "struct_tag" ... You would most likely be best off just fully declaring it.
sizeof
运算符是在编译时而不是运行时计算的,因此在这一行:编译器没有有关结构大小的信息。
解决方案包括:
initialize_ports()
。initialize_ports()
调用 ports.c 中定义的函数以在运行时获取Port_t
的大小。无论如何,您都不应该在头文件 driver.h 中定义
initialize_ports()
,除非您的编译器支持inline
或_inline< /code> 关键字并且您使用它。然而,这种用法会使代码不符合 ISO C 标准,因此可移植性较差,但是由于 C++ 对关键字的标准支持,您可能会发现它是大多数包含 C++ 编译的 C 工具链中的扩展,只要您不会使用过于严格的合规选项。
但是,您收到的错误消息是出于不同的原因。与 C++ 不同,C
struct_tag
本身并不表示类型(如果确实如此,您就不需要typedef
!),您必须使用struct< /code> 关键字。
The
sizeof
operator is evaluated at compile time not runtime, so at the line:the compiler has no information regarding the size of the structure.
Solutions include:
initialize_ports()
in port.c after the struct is fully defined.initialize_ports()
call a function defined in ports.c to get the size ofPort_t
at run-time.In any case you should not define
initialize_ports()
in the header file driver.h unless your compiler supports theinline
or_inline
keyword and you use it. Such usage would however render the code non ISO C compliant, and therefore less portable, however due to C++'s standard support for the keyword, you are likely to find it as an extension in most C tool-chains that include C++ compilation, so long as you do not use excessively strict compliance options.However the error message you are getting is for a different reason. Unlike C++ in C
struct_tag
alone does not represent a type (if it did, you'd not have needed thetypedef
!), you must use thestruct
keyword.