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
我只是想知道如何转发声明并能够将结构作为参数传递?
非常感谢任何建议,
答案 0 :(得分:7)
您应该使用:
int initialize_ports(struct struct_tag *port);
^^^^^^
此外,前向声明会为您提供不完整类型,您不知道其大小。如果您需要分配struct struct_tag
,则需要包含完整定义。或者,如果要使其完全不透明,可以使用一些create_struct_tag()
函数。
答案 1 :(得分:5)
正如其他答案所述,您可以在原型中将struct_tag
更改为struct struct_tag
。获取代码编译的另一种方法是编写
typedef struct struct_tag struct_tag;
代替现有的struct struct_tag;
(即将typedef与前向定义结合起来)。那确实允许你写
int initialize_ports(struct_tag *port)
没有编译失败。但是,这仍然不是你想要的,因为调用者既不能分配这种类型的局部变量,也不能分配malloc(),因为他们不知道大小。
其他答案表明你应该打开结构的定义。这通常不是正确的答案 - 因为它删除了您尝试创建的抽象层。更好地拥有函数(在port.c
中,即 了解内部的库),例如:
struct_tag *create_port(...);
void free_port(struct_tag *port)
即。创建和释放结构 - 实际上也用于其他操作(例如读取/写入结构)。
答案 2 :(得分:1)
你会得到一个错误,因为你不知道“端口”的大小,因为所有它必须继续是前向声明。
总之,除非你还设置一个大小为“struct_tag”的常量值,否则你最好不要在这里使用前向声明...你最有可能只是完全声明它。
答案 3 :(得分:1)
在编译时而非运行时评估sizeof
运算符,所以在以下行:
port = malloc(sizeof *port);
编译器没有关于结构大小的信息。
解决方案包括:
initialize_ports()
。initialize_ports()
调用ports.c中定义的函数,以便在运行时获得Port_t
的大小。在任何情况下,除非您的编译器支持initialize_ports()
或inline
关键字,否则您应该不在头文件driver.h中定义_inline
你使用它。然而,这样的使用会使代码不符合ISO C,因此不太便于移植,但是由于C ++对关键字的标准支持,您可能会发现它是包含C ++编译的大多数C工具链的扩展,只要你没有使用过于严格的合规选择。
但是,您收到的错误消息是出于其他原因。与C中的C ++不同,{C} {1}}不代表某种类型(如果有,则不需要struct_tag
!),您必须使用typedef
关键字。