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... 名称;