【问题标题】:forward declaration of typedefed structstypedef 结构的前向声明
【发布时间】:2014-11-25 11:26:51
【问题描述】:

在 C 中,结构通常是类型定义的,以避免到处都写结构。

当在头文件中将此名称用作不透明指针参数时,您必须转发声明它们。必须复制整个 typedef 是相当烦人的。

例子:

一些头文件定义了一些类型:

typedef struct sBlaBlaFooBar{
 int someData;
}BlaBlaFooBar;

其他一些头文件使用这个结构作为指针参数。但是为了避免巨大的包含依赖,不应该包含 BlaBlaFooBar.h,而只使用前向声明。

所以你必须写typedef struct sBlaBlaFooBar BlaBlaFooBar;来转发声明它。

令我困扰的是我必须知道结构的标签名称的冗余,因为通常这无关紧要。如果改变了,所有的前向声明也必须改变,即使类型名相同。

有什么聪明的办法解决这个问题吗?


更详细的解释:

  • 很多带有结构定义的标题(也可能是组合结构(只是为了显示深度依赖图))
    • s1.h
    • s2.h
    • s3.h
    • s4.h
  • 带有BlaBlaFooBar 结构的 BlaBlaFooBar 标头,是所有这些的组合。
  • 具有相似拓扑结构的其他结构 BlaBlaBarFoo(来自其他子结构)
  • 然后是定义新结构NewStruct 和函数NewStruct_create(NewStruct* out, const BlaBlaFooBar* in); 处理的模块 上述结构作为输入。这些标头只需要 typedef,并且只有实现必须知道确切的 BlaBlaFooBar 结构定义。
  • 仅适用于 NewStruct 的附加模块,如果 BlaBlaFooBar 发生更改,则不必重新编译。

因此,为了避免这种依赖关系,必须在头文件中前向声明结构,并且 c 文件包含定义。

【问题讨论】:

  • 库供应商应该在她自己的、带有稳定 typedef 名称的随附标头中提供前向声明。然后供应商可以根据她的喜好更改内部名称,而您永远不会知道。

标签: c coding-style forward-declaration


【解决方案1】:

使用 2 个包含文件:

blabla.h

#include "light_dependencies.h"
typedef struct sBlaBlaFooBar BlaBlaFooBar;

blabla_internal.h

#include "blabla.h"
#include "heavy_dependencies.h"
struct sBlaBlaFooBar {
    ...
};

blabla.c

#include "blabla_internal.h"
/* Here is code which deals with the internals of the struct */

usercode.c

#include "blabla.h"
/* Here is code which only passes struct pointers around */

【讨论】:

  • 这似乎是最好的方法。创建一个只前向声明结构的标头,以便可以使用一致的前向声明。这样只有真正需要的标题必须包含结构定义及其所有依赖项。
  • 获得不透明指针的好方法。比使用 void* 更好,因为这样可以保留强类型。
猜你喜欢
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
  • 1970-01-01
  • 2012-06-09
相关资源
最近更新 更多