符号表由C ++编译器创建

时间:2014-10-22 19:38:48

标签: c++ visual-c++ compiler-construction symbols effective-c++

我正在阅读 Effective C ++ ,第3版和第2项(更喜欢const,枚举和内联到#defines ),Scott Meyers提到符号表格:他解释说#defines可能不会出现在符号表中。

根据答案here,其中一些建议的readingWikipedia文章,我将按如下方式定义符号表:因为编译器只创建目标文件对于每个翻译单元,我们仍然需要一种在翻译单元之间引用符号的方法。这是使用为每个目标文件创建的表来完成的,以便在以后阶段定义符号 - 当从目标文件创建可执行文件/库时,链接器可以定义符号。在链接期间,符号是链接器用适当的内存地址替换的。

这是我想知道的:

  • 我的解释是否正确?
  • 链接后,一旦解析了内存地址,我认为不需要符号表吗?也就是说,我认为符号表在可执行文件/库中不可用;那是对的吗?
  • 我怀疑符号表对其他编译器任务也有用吗?或许像识别命名冲突一样?
  • 上述符号表与export table不同。至少在Visual C ++的上下文中,导出表定义了在库外明确声明为可见的符号。我想在某种意义上说这是一个符号表 - 但与Scott所指的符号表无关。
  • 符号表还有什么有趣的吗?也就是说,我应该对符号表有任何额外的见解吗?

感谢您的时间和贡献。

1 个答案:

答案 0 :(得分:5)

符号表同时存在于编译器中(然后编译器甚至将局部变量符号放入其中;甚至preprocessor也有#define - d名称的某种符号表,但预处理器可能在今天的编译器内部)和链接器。但这些是不同的表格,组织方式不同。

链接器符号表主要用于导出或导入的全局符号。请注意,linker会执行一些relocation。请注意,链接器在Windows和Linux上的行为完全不同(Windows上为dllimport,Linux上为__attribute__(visibility...)。请注意,对于动态库,某些链接在运行时发生(dynamic loading)。对于C ++,name mangling可能会发生。另请阅读vague linkage& template instantiation& link-time optimization中的GCC ...

另请阅读Levine's book: Linkers and Loaders,例如ELF格式的wikipage(用于Linux和许多Unix系统上的目标文件,共享库和可执行文件)。

如果您可以访问某些Linux系统,请使用readelf(1)nm(1)objdump(1)实用程序。另请阅读Drepper's paper: How To Write Shared Libraries(在Linux上)