【发布时间】:2015-09-19 16:20:13
【问题描述】:
我想知道编译 C++ 程序产生的 .o 或 .so 文件中究竟存储了什么。 This post 很好地概述了编译过程和其中的 .o 文件的功能,据我了解 this post , .a 和 .so 文件只是多个 .o 文件合并为一个以静态 (.a) 或动态 (.so) 方式链接的文件。
但我想检查一下我是否正确理解了此类文件中存储的内容。编译如下代码后
void f();
void f2(int);
const int X = 25;
void g() {
f();
f2(X);
}
void h() {
g();
}
我希望在 .o 文件中找到以下项目:
-
g()的机器代码,包含调用f()和f2(int)的一些占位符地址。 -
h()的机器代码,没有占位符 -
X的机器码,即数字25 - 可以找到某种表格,指定文件中符号
g()、h()和X的地址 - 另一个表指定了哪些占位符用于引用未定义符号
f()和f2(int),在链接期间必须解决这些符号。
然后像nm 这样的程序会列出两个表中的所有符号名称。
我想编译器可以通过调用 f2(25) 来优化调用 f2(X),但它仍然需要将符号 X 保留在 .o 文件中,因为无法知道它是否会被使用一个不同的 .o 文件。
这样说对吗? .a 和 .so 文件是一样的吗?
感谢您的帮助!
【问题讨论】:
-
这些文件中有位 (0,1)... ;) [我无法抗拒,我 100% 确定某处有一个“好”的答案,有人会标记这个作为一个骗子]
-
在 C++ 中,与 C 不同,所有使用
const注释的命名空间级对象都具有内部链接,除非使用extern显式“发布”。因此,在您的情况下,C++ 编译器有权优化X。至于你的问题,我建议尝试使用objdump和readelf实用程序,它们允许探索.o、.a和.so文件的内容。 -
@Mats:给我看一个没有位的文件 :-) [我知道,一个空文件...]
-
内联函数的工作方式略有不同。 C++ 标准规定每个使用内联函数的编译单元 (CU) 必须 对其进行定义。因此,如果在 CU 中不使用内联函数,编译器有权(但没有义务)将其丢弃。但是,GCC 有 certain pragmas 来缓解代码膨胀。
-
他们当然不能。没有办法声明一个类的静态数据成员不能从另一个编译单元访问。
标签: c++ c compilation object-files archive-file