6

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

根据这里的答案,一些建议的阅读,以及维基百科的文章,我将符号表定义如下:由于编译器只为每个翻译单元创建目标文件,我们仍然需要一种方法来引用符号之间的符号翻译单位。这是使用为每个目标文件创建的表来完成的,以便可以在稍后阶段定义符号 - 在从目标文件创建可执行文件/库时由链接器定义。在链接过程中,符号被链接器替换为相应的内存地址。

这是我想知道的:

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

感谢您的时间和贡献。

4

1 回答 1

5

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

链接器符号表主要用于导出或导入的全局符号。请注意,链接器会执行一些重定位。请注意,链接器在 Windows 和 Linux 上的行为完全不同(dllimport在 Windows 上,__attribute__(visibility...)在 Linux 上)。请注意,对于动态库,一些链接发生在运行时(动态加载)。对于 C++,可能会发生名称修改。另请阅读有关GCC中的模糊链接模板实例化链接时间优化...

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

如果您可以访问某些 Linux 系统,请使用readelf(1)nm(1)objdump(1)实用程序。另请阅读Drepper 的论文:如何编写共享库(在 Linux 上)

于 2014-10-22T19:46:22.260 回答