std::string有超过 30 个可以在字符串对象上调用的成员函数。
如果我只使用其中的几个呢?
我假设未使用的成员函数不会占用可执行代码部分的空间。
我很想知道链接器是否有可能确定未使用的成员函数,将其从已编译二进制文件的一部分中删除,并报告它丢弃了哪些函数。
有没有办法做到这一点?我正在查看gcc 的链接器标志,但找不到任何相关内容。
std::string有超过 30 个可以在字符串对象上调用的成员函数。
如果我只使用其中的几个呢?
我假设未使用的成员函数不会占用可执行代码部分的空间。
我很想知道链接器是否有可能确定未使用的成员函数,将其从已编译二进制文件的一部分中删除,并报告它丢弃了哪些函数。
有没有办法做到这一点?我正在查看gcc 的链接器标志,但找不到任何相关内容。
因为std::string
是一个模板类(std::string
只是一个typedef
to std::basic_string<char>
),所以只会实例化使用的方法,所以不会编译未使用的方法,因此它们不能从您的可执行文件中删除。
关于非模板类:virtual
函数将始终以可执行文件结尾,无论它们是否被调用,因为 vtable 需要地址。来自可执行文件或静态链接库的源的其他方法(以及自由函数)只有在实际使用时才会链接到二进制文件中。但我知道没有链接器标志来打印尚未链接的功能。
另一方面,共享库 (.so) 必须包含所有(导出的)函数和方法,因为使用此共享库的二进制文件可以使用任何(导出的)函数。但是由于共享库可以被许多可执行文件使用,而只加载到内存中一次,这通常是值得的。
标准库通常是共享的,因此它不会占用可执行文件中的任何空间。
如果您静态链接,那么就链接器而言,非虚拟成员函数只是您的常规花园品种功能,名称很有趣。无论链接器对普通函数做什么,它都可以对非虚拟成员做什么。我认为 GNU LD 可能能够在某些架构上删除未使用的功能,但不能在其他架构上删除。
当然,功能模板、成员等std::string
完全是另外一回事。对于链接器,它们根本不是来自库,而是来自您的对象(并且只有您实例化的对象)。
这个答案并不完全涵盖您的情况,但是如果您想知道您的类是否有任何未调用的函数,一些静态分析工具(如cppcheck)会报告这一点。