typedef struct name 没有后续结构定义的名称

Posted

技术标签:

【中文标题】typedef struct name 没有后续结构定义的名称【英文标题】:typedef struct name name without a subsequent struct definition 【发布时间】:2015-05-08 11:53:17 【问题描述】:

我在 libelf 库的 libelf.h 的第 153-154 行找到了以下代码:

/* Descriptor for the ELF file.  */
typedef struct Elf Elf;

我正在寻找Elf 的结构定义,但没有找到。

在后面的代码中,Elf 被使用,例如

/* Return descriptor for ELF file to work according to CMD.  */
extern Elf *elf_begin (int __fildes, Elf_Cmd __cmd, Elf *__ref);

在线程 Why should we typedef a struct so often in C? 中,用户“unwind”说:

另请注意,虽然您的示例(和我的示例)省略了命名 struct 本身,当你想提供 > opaque 类型时,实际上命名它也很有用。然后你会在标题中有这样的代码,例如:

typedef struct Point Point;

Point * point_new(int x, int y);

然后在实现文件中提供struct 声明。

然而,我也无法在任何 c 文件中找到结构 Elf 的定义。

我错过了什么?没有结构定义的typedef struct Name_xy Name_xy; 的目的是什么?或者这是不可能的,我只是没有找到结构定义?


编辑:

首先,感谢您的众多精彩回复。由于我的问题是双重的(至少),所以有两个答案:

    我没有找到定义,因为我没有lib/private.h 文件(感谢@molbdnilo 指出定义在其中)。我安装了elfutils 的源代码而不是libelf 的源代码。 private.h 似乎没有包含在elfutils 源码包中。 @Acrasidae、@sfjac 和 @Matt McNabb 的答案解释了概念背景(不透明类型、封装、最小化依赖关系......)。

【问题讨论】:

可能是在另一个你没有检查过的头文件中定义的? typedef struct X X 只是为了防止在 C 中每次使用之前编写 struct 的约定,我认为这个定义是肯定的。 也许这个库是一个没有源文件的预编译库? @EugeneSh。 :我做了一个apt-get source 来获取源文件。而且文件夹里还有很多.c文件…… 定义应该在“private.h”中。 【参考方案1】:

在 C++ 中,struct Elf 应该足以声明类型,这就是返回指向该类型的指针所必需的。通常这样做是为了向头文件的用户隐藏实现,这些用户本身不会使用Elf 功能,但可能只是传递指针。以这种方式编码消除了对实际未使用的头文件的不必要依赖。这种最小化头文件依赖的方法会对大型 C++ 项目的编译时间产生很大影响。

正如其他人所提到的,typedef struct Elf Elf 是 C 的东西,允许您在以后的声明中省略 struct

【讨论】:

【参考方案2】:

typedef struct Elf Elf;是一种简写方式:

struct Elf;

typedef struct Elf Elf;

这些行做不同的事情。第一个通常称为前向声明。这意味着我们以后可以有这样的代码:

// function prototype
struct Elf *elf_begin( stuff.... );

它原型化了一个返回指向struct Elf 的指针的函数,即使我们实际上并不知道struct Elf 的主体中包含什么。这有时称为不透明类型,它的另一个实例是 C 标准库中的FILE *。任何地方都可能没有struct Elf 的定义。

第二部分,typedef struct Elf Elf;,正如你在问题中所说,主要是为了避免一直输入struct

【讨论】:

您写“可能在任何地方都没有 struct Elf 的定义”。我认为这里可能就是这种情况,因为Elf 类型是“ELF 文件的描述符”。从实际的角度来看,有一个 Elf 头的 struct 定义就足够了。 McNabb :我不确定您关于“任何地方都可能没有定义”的说法。请参阅@Acrasidae 的答案和 cmets。你能提供一些关于你的陈述的细节吗? @***www 库开发人员可能有一个用于编译库的定义,但如果您只使用库头和库的编译二进制文件,那么该定义将不存在【参考方案3】:

是否在 decl.h 中定义?

例如:

http://www.opensource.apple.com/source/dtrace/dtrace-96/head/libelf.h http://www.opensource.apple.com/source/dtrace/dtrace-118/libelf/decl.h

【讨论】:

点击libelf/decl.h!什么是 dtrace?为什么decl.h 不是 libelf 资源的一部分?【参考方案4】:

对此的可能解释可能是您的项目有一些预编译的库文件,其中包含struct Elf 的定义。

【讨论】:

我使用了apt-get source。如何检查我是否有预编译文件?说你是对的,可以从这样的预编译文件中获取结构定义吗?【参考方案5】:

我错过了什么? typedef struct Name_xy Name_xy 的目的是什么?没有结构定义?或者这是不可能的,我只是没有找到结构定义?

在 libelf.h 中,您有一个不透明类型的声明:Elf。

但是,你没有找到 Elf 结构的定义,你想知道为什么。

首先,有一个definition,看起来像struct Elf...;,但是你不能访问这个定义,因为开发者不希望您访问它。您可以使用 Elf 结构的内容的唯一方法是因为在 libelf.h 中有这个声明,typedef struct Elf Elf;。顺便说一句,struct Elf; 是完全一样的,但是使用 typedef 我们知道类型不透明的可能性更大。

一个更详细的例子:

头文件:

/* libelf.h */
typedef struct Elf Elf;
extern Elf *elf_begin (int __fildes, Elf_Cmd __cmd, Elf *__ref);
etc...

实现文件:

/* libelf.c */
struct Elf 
  char * something;
  FILE * whatever;
;

Elf *elf_begin (int __fildes, Elf_Cmd __cmd, Elf *__ref)
  /*doing something;*/
  /* ... */

etc...

这正是封装的原理。这种类型的内容只有API函数的实现是已知的并且可以访问的,客户端(你)不能直接访问它的内容。对于开发人员,他们必须编译一个共享库,所以你可能会在某个地方找到类似 libelf.so 的东西(我不知道 libelf 做了什么,所以我无法帮助你)。 关于封装的目的,我建议你阅读this。

我没有别的想法,但如果您还有其他问题,请不要犹豫。

【讨论】:

你写道:“首先,在某处有一个定义,看起来像 struct Elf...;”。这与@Matt McNabb 的声明“可能在任何地方都没有 struct Elf 的定义”相矛盾。我不确定该怎么想... 好吧,我确实认为有一个定义...否则,您甚至无法在没有编译时错误的情况下键入“typedef struct Elf Elf”。马特麦克纳布应该带来一些关于他的声明的细节。 lib/private.h 中结构定义的存在支持您的两个观点:结构定义存在,并且出于封装原因它不在文件中(private.h) .

以上是关于typedef struct name 没有后续结构定义的名称的主要内容,如果未能解决你的问题,请参考以下文章

C : typedef 结构名称 ...; VS typedef struct... 名称;

三言两语搞懂c语言之struct与typedef(小白必看)

C++ 类 Typedef Struct 没有命名类型

struct和typedef struct

struct和typedef struct

struct和typedef struct