繁体   English   中英

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

[英]typedef struct name name without a subsequent struct definition

我在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);

在线程中我们为什么要在C中经常键入一个结构? ,用户“放松”说:

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

typedef struct Point Point;

Point * point_new(int x, int y);

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

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

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


编辑:

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

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

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

正如其他人提到的那样, typedef struct Elf Elf是一个C typedef struct Elf Elf ,允许你在将来的声明中删除struct

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

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

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

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

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

首先,某处有一个定义 ,看起来像struct Elf {...}; 但是,您无法访问该定义,因为开发人员不希望您访问它。 你可以使用Elf结构内容的唯一方法是因为有这个声明, typedef struct Elf Elf; ,在libelf.h中。 顺便说一下, 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...

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM