【问题标题】:How to partially declare a struct that is typedef'ed when in an include file如何在包含文件中部分声明类型定义的结构
【发布时间】:2012-03-15 17:24:05
【问题描述】:

作为一般做法,我正在尝试尽量减少 #include 文件的相互依赖性。

在 xxx.h 我有:

struct my_struct;  // partial decl to satisfy use of my_struct*
void funct(struct my_struct* ms);  // uses the partial def

如何用 typedef 的结构做类似的部分 decl? 我在第三个 #include 中有一个实际的 decl,看起来像(比如在 yyy.h 中):

typedef struct my_data_s {
  int ival;
  ... struct's other components ...
} my_data_t;

我只想要一个在 xxx.h 中引用 typedef 的有代表性的 decl:

typedef struct my_data_s  my_data_t;  // actual full decl is elsewhere
void funct2(my_data_t* md);   

此尝试导致“重新定义 typedef my_data_t”错误。 (使用 gcc 4.4.3 / Ubuntu 10.4)其他随机搜索尝试(例如,在 typedef 中添加“{}”)也会出错。

我知道编译器只需要知道函数需要一个指针,所以这似乎应该是可能的。到目前为止,没有发现编译时没有错误/警告。

我查看了其他问题和答案,找不到解决的问题。似乎应该有一种众所周知的方法来做到这一点(?!)(我知道我可以在 #include xxx.h 时 #include yyy.y - 试图避免这种依赖关系。)谢谢。

【问题讨论】:

    标签: c include typedef


    【解决方案1】:

    你试过简单的方法吗:?

    xxx.h

    struct my_data_s;
    typedef struct my_data_s my_data_t;
    

    yyy.h

    #include "decl.h"
    struct my_data_s {
       int foo;
    };
    

    【讨论】:

    • 和我的单行版有同样的错误。谢谢你的想法!
    • @ArtSwri:你并没有真正按照他说的去做,是吗?重要的部分是不要重复typedef(这正是错误消息所抱怨的)。
    【解决方案2】:

    C99 不允许重复 typedef,C11 允许。

    只需执行一次typedef 并始终先获得它:

    typedef struct my_data  my_data;
    

    也无需为struct 标记和typedef 标识符选择不同的名称。

    【讨论】:

    • (我知道你可以为 struct 和 typedef 使用相同的名称,应该提到这一点。我们按照命令遵循编码规范。)执行 typedef 一次意味着将它与 struct decl (还是我误解了?)
    • @ArtSwri:typedef 与实际的struct 声明分开有什么关系?它仍然在前向声明旁边。
    • @jamesdlin,struct 标签本身不需要任何前向声明。由于struct 关键字,很明显它指的是一个结构。首先单独放置typedef 允许您始终使用不带struct 关键字的typedef 名称,即使在struct 的实际声明中也是如此。
    • @JensGustedt:是的,我知道这一点。我的评论是针对 Art,他愚蠢地反对仅在前向声明的位置使用 typedef。谁在乎它是否与具体定义分开。
    【解决方案3】:

    这是我们小组决定做的事情。它代表了几个相互冲突的要求/愿望的折衷。我发帖是为了展示另一种方法,所以这篇文章的读者有多种选择。它代表了我们情况的最佳答案。

    obj_a_defs.h

    // contains the definition
    // #include'd only by other .h files
    ...
    #define ... // as needed for struct definition
    ...
    typedef struct obj_a {
      ...
    } obj_a;
    

    obj_a.h

    // contains the 'full info' about obj_a: data and behaviors
    // #include'd by other .c files
    ...
    #include "obj_a_defs.h"
    ...
    // declares functions that implement 
    // the behaviors associated with obj_a
    

    obj_a.c

    ...
    #include "obj_a.h"
    ...
    // implementations of functions declared in obj_a.h
    

    obj_b.h

    // a 'user' of obj_a that uses obj_a as arg
    #include "obj_a_defs.h"  // to get the typedef    
    ...
    int some_b_funct(obj_a* obja, ...);
    ...
    

    obj_b.c

    // Defines the 'contract' that this implementation
    // is meeting.
    #include "obj_b.h"
    ...
    // This .c file includes obj_a.h only if it
    // uses the functions defined for obj_a.
    // If obj_a is used only to 'pass through'
    // to other modules, there's no need for 
    // this include.
    #include "obj_a.h"  // only if obj_b uses 
    ...
    // obj_b's function implementations
    

    基本原理/条件

    • typedef 和 struct 保持在一起
    • 使用 obj_X 的 .c 文件必须#include "obj_X.h" 显示使用
    • 避免使用 .h 文件,包括一般的其他 .h 文件; .h 文件中只有“defs.h”文件是#include'd。
    • 避免#include'ing 文件只是为了处理依赖关系; IOW 避免 #include'ing obj_a.h 只是因为它在 obj_b.h 中使用

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多