前向 typedef 结构

发布于 2024-10-02 12:31:46 字数 643 浏览 7 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

最近可好 2024-10-09 12:31:46

您应该使用:

int initialize_ports(struct struct_tag *port);
                     ^^^^^^

此外,前向声明会给您一个您不知道其大小的不完整类型。如果您需要分配一个struct struct_tag,您需要包含它的完整定义。或者,如果您想使其完全不透明,您可以使用一些 create_struct_tag() 函数。

You should use:

int initialize_ports(struct struct_tag *port);
                     ^^^^^^

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 some create_struct_tag() function if you want to make it fully opaque.

旧街凉风 2024-10-09 12:31:46

正如其他答案所指出的,您可以在原型中将 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)

即创建和释放结构 - 实际上是为了其他操作(例如读取/写入结构)也是如此。

As other answers have noted, you could change struct_tag to struct struct_tag in the prototype. Another way of getting your code to compile is to write

typedef struct struct_tag struct_tag;

in place of your existing struct struct_tag; (i.e. combine the typedef with the forward definition). That then does allow you to write

int initialize_ports(struct_tag *port)

without 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:

struct_tag *create_port(...);
void free_port(struct_tag *port)

i.e. to create and free the structures - and indeed for other operations (such as reading from / writing to the structure) too.

瞎闹 2024-10-09 12:31:46

您会收到错误,因为您不知道“端口”的大小,因为它所要做的只是前向声明。

总之,您最好不要在这里使用前向声明,除非您还设置了一个常量值,即“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.

各自安好 2024-10-09 12:31:46

sizeof 运算符是在编译时而不是运行时计算的,因此在这一行:

port = malloc(sizeof *port);

编译器没有有关结构大小的信息。

解决方案包括:

  • 在头文件中完全定义类型。
  • 结构体完全定义后,在 port.c 中定义 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:

port = malloc(sizeof *port);

the compiler has no information regarding the size of the structure.

Solutions include:

  • fully define the type in the header file.
  • define initialize_ports() in port.c after the struct is fully defined.
  • have initialize_ports() call a function defined in ports.c to get the size of Port_t at run-time.

In any case you should not define initialize_ports() in the header file driver.h unless your compiler supports the inline 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 the typedef!), you must use the struct keyword.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文