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

时间:2015-05-08 11:53:17

标签: c++ c struct typedef elf

我在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?中,用户"放松"表示:

  

另请注意,虽然您的示例(和我的)省略了命名struct   本身,实际命名它也适用于你想提供一个>不透明的类型。然后你在标题中有这样的代码,例如:

     

typedef struct Point Point;

     

Point * point_new(int x, int y);

     

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

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

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

修改

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

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

5 个答案:

答案 0 :(得分:3)

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

正如其他人所提到的,typedef struct Elf Elf是一个C事物,允许你在将来的声明中忽略struct

答案 1 :(得分:3)

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

struct Elf;

typedef struct Elf Elf;

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

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

该函数原型化一个函数,该函数返回指向struct Elf的指针,即使我们实际上并不知道struct Elf正文中包含的内容。这有时称为 opaque类型,而C标准库中的另一个实例是FILE *。任何地方都可能没有struct Elf的定义。

正如您在问题中所说,第二部分typedef struct Elf Elf;主要是避免必须始终键入struct

答案 2 :(得分:1)

答案 3 :(得分:0)

可能的解释可能是您的项目有一些预编译的库文件,其中包含<p id="storyStarter" onclick="document.getElementById(&quot;storyStarter&quot;).innerHTML=&quot;&quot;; printLetterByLetter(&quot;storyStarter&quot;,&quot; It all begins here&quot;,50)">Click To begin Story</p> <a onclick="empty(&quot;storyStarter&quot;)">Clear Text</a>的定义。

答案 4 :(得分:0)

  

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

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

但是,您没有找到Elf结构的定义,而您想知道原因。

首先,某处有一个定义,它看起来像 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这样的东西(我不知道自己做了什么,所以我无法帮助你)。 关于封装的目的,我建议你阅读this

我没有别的想法,但如果你有更多问题,请不要犹豫。