c++ - 存储在 C++ 编译器中的标识符的定义(不是声明)在哪里?
问题描述
我在这个问题上经历了很多答案,但我仍然很困惑。
我知道头文件包含标识符的声明,而库包含这些的定义?我们可以访问编译器中关联的 .h 文件,但如何访问库文件?
还有一个问题
我们在程序中只包含头文件,那么库文件如何链接到它?
解决方案
让我试着用一个例子来说明
头文件.h
int func(int in);
a.cpp
#include "header.h"
int main(int argc, const char** argv)
{
int b = func(2);
return 0;
}
b.cpp
#include "header.h"
int func(int in)
{
return in*2;
}
现在让我们编译
g++ -c -o a.o a.cpp
我们可以看一下生成的目标文件的符号表
objdump -t a.o
a.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 a.cpp
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 g F .text 0000000000000023 main
0000000000000000 *UND* 0000000000000000 _GLOBAL_OFFSET_TABLE_
0000000000000000 *UND* 0000000000000000 _Z4funci
因此,我们看到在 a.cpp 中定义的 main 函数,我们还看到了一个名为_Z4funci
(这是标识“func”)的条目,但它被标记为未定义(*UND*
地址之前)。所以链接器稍后会在另一个对象中查找它。
现在让我们看看b
g++ -c -o b.o b.cpp
objdump -t a.o
b.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 b.cpp
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 g F .text 000000000000000e _Z4funci
有定义_Z4funci
现在您可以将两者链接在一起以创建完整的可执行对象
g++ a.o b.o -o out
./out
如果您想知道_Z4funci
名称是如何决定的,请阅读“C++ name-mangling”
推荐阅读
- javascript - Javascript Audio Play() 函数不播放所有声音
- javascript - TypeScript 类工厂需要一个交集
- r - R 中的人口模型错误:`$<-.data.frame`(`*tmp*`, "Age", value = NA) 中的错误:替换有 1 行,数据有 0
- typescript - 打字稿错误:TS2345:类型参数'{主题:字符串;json文件:字符串;输出:字符串;}; }' 不可分配给“选项”类型的参数
- javascript - 打字稿/javascript删除嵌套对象数组中的对象部分重复
- templates - UWP:除了 ItemsWrapGrid 之外,还有其他 ItemsPanelTemplate(s)
- excel-formula - 按比例休假计算
- jenkins-pipeline - 为什么生成 DSL 时 Jenkins.get().getRootUrl() 不可用?
- linux - 一次运行多个作业并检查哪一个失败
- rust - Rust:用最少的小数点格式化浮点数