c++ - C++编译器创建的符号表

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

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

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

这是我想知道的:

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

感谢您的时间和贡献。

最佳答案

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

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

另请阅读 Levine's book: Linkers and Loaders和例如ELF 上的维基页面格式(用于 Linux 和许多 Unix 系统上的对象文件、共享库和可执行文件)。

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

关于c++ - C++编译器创建的符号表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26515723/

相关文章:

c++ - 有没有办法将游戏列表信息从 Steam 获取到桌面应用程序中?

java - 并行计算开销

parsing - 手动计算第一组

c++ - WxWidgets:简单的数学公式给出错误的结果?

c++ - 使用环境变量 C++ 在 Linux 上用 C++ 启动进程

c++ - 在 main() 中调用函数变量后访问函数变量

C++ 语法 : error conversion from some_type to non-scalar_type requested

c++ - libcurl:一段时间后,curl_easy_perform 失败并显示 CURLE_SSL_CACERT_BADFILE

java - 64 位编译器中的 JNI 未解析的外部符号 __imp_JNI_CreateJavaVM

c++ - 将声明为 `extern char[]` 的变量传递给 VC++ 中的函数模板时出错