有一个非常小的项目:
功能c2.cpp:
#include <iostream>
void myfunc2()
{
std::cout << "Func2 called" << std::endl;
}
功能cpp:
#include <iostream>
#include "func.h"
void myfunc()
{
std::cout << "Hallo func " << std::endl;
}
主.cpp:
#include "func.h"
#include "func2.h"
int main()
{
//myfunc(); // intentionally moved away!
//myfunc2();
}
.h文件只有所需函数的定义。
生成文件:
all: go
%.o: %.cpp
g++ -O3 -fdata-sections -ffunction-sections $< -c
go: main.o func.h func.o func2.o func2.h
g++ -fdata-sections -ffunction-sections main.o func.o func2.o -o go -Wl,--gc-sections
如果我对生成的可执行文件进行分解,仍然会得到两个不需要的函数:
0000000000400560 <_GLOBAL__sub_I__Z6myfuncv>:
400560: 48 83 ec 08 sub $0x8,%rsp
400564: bf 31 10 60 00 mov $0x601031,%edi
400569: e8 c2 ff ff ff callq 400530 <std::ios_base::Init::Init()@plt>
40056e: ba 30 07 40 00 mov $0x400730,%edx
400573: be 31 10 60 00 mov $0x601031,%esi
400578: bf 40 05 40 00 mov $0x400540,%edi
40057d: 48 83 c4 08 add $0x8,%rsp
400581: e9 9a ff ff ff jmpq 400520 <__cxa_atexit@plt>
400586: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
40058d: 00 00 00
0000000000400590 <_GLOBAL__sub_I__Z7myfunc2v>:
400590: 48 83 ec 08 sub $0x8,%rsp
400594: bf 32 10 60 00 mov $0x601032,%edi
400599: e8 92 ff ff ff callq 400530 <std::ios_base::Init::Init()@plt>
40059e: ba 30 07 40 00 mov $0x400730,%edx
4005a3: be 32 10 60 00 mov $0x601032,%esi
4005a8: bf 40 05 40 00 mov $0x400540,%edi
4005ad: 48 83 c4 08 add $0x8,%rsp
4005b1: e9 6a ff ff ff jmpq 400520 <__cxa_atexit@plt>
4005b6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
4005bd: 00 00 00
看起来每个需要iostream对象的文件都会生成一个函数,该函数在初始化期间调用。节和生成的函数从该文件中第一个定义的函数中获取名称。
如果我不使用这个函数,并且它在最终的可执行文件中没有链接,那么
_GLOBAL__sub_I__xxxx
功能仍然存在。我怎样才能移除它们?
在我看来,IOstream对象的每个用户
cout
将生成其他初始值设定项函数。有什么办法可以摆脱它吗?我觉得每个可执行文件只需要一次,但我看到了多次。一般来说,如何避免?