[英]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;
没有结构定义? 或者这是不可能的,我只是没有找到结构定义?
编辑:
首先,感谢您的无数精彩回复。 由于我的问题是双重的(至少),有两个答案:
lib/private.h
文件(感谢@molbdnilo指出定义在那里)。 我安装了elfutils
的来源而不是libelf
。 似乎private.h
不包含在elfutils
源包中。 在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.