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

Poo*_*ven 6 c++ compiler-construction symbols effective-c++ visual-c++

我读的有效C++,第3版和第2项(喜欢常量,枚举和内联到#定义),斯科特迈尔斯提到的符号表:他解释说,#defines可能不会出现在符号表.

基于答案在这里,有点的建议阅读它们,和维基百科的文章,我会按照如下方式定义符号表:因为编译器只为每一个翻译单元创建对象文件,我们还需要一种方式来引用符号之间翻译单位.这是使用为每个目标文件创建的表来完成的,以便可以在以后阶段定义符号 - 当从目标文件创建可执行文件/库时,链接器可以定义符号.在链接期间,符号由链接器替换为其适当的内存地址.

这是我想知道的:

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

感谢您的时间和贡献.

Bas*_*tch 5

符号表存在两种编译器(然后编译器甚至让局部变量符号在其中;即使是预处理器具有某种对符号表的#define-d名字,但预处理器可能是编译器里面的今天)和链接器.但这些是不同的表格,组织方式不同.

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

另请阅读Levine的书:链接器和加载器,例如ELF格式的wikipage (用于Linux和许多Unix系统上的目标文件,共享库和可执行文件).

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