GCC不会删除未使用的函数

3
我正在编写一些代码,这些代码将用于嵌入式设备,所以我希望通过让链接器丢弃我不使用的第三方库函数来减小代码大小。我尝试了使用 -ffunction-sections-fdata-sections 选项以及 -Wl,--gc-sections,但未使用的函数仍然存在。
这是我用MinGW构建的一个示例:
#include <iostream>
using namespace std;

double unused_function(int a, int b)
{
    double r;

    r = (double)a + (1.0/ (double)b);

    return r;
}

double used_function(int a, int b)
{
    double r;

    r = (double)a + (1.0/ (double)b);
    cout << r << "is the value" << endl;

    return r;
}

int main() {
    cout << "!!!Hello World!!!" << endl;

    used_function(4,5);
    return 0;
}

这是命令行输出:
g++ -O1 -ffunction-sections -fdata-sections -g -Wall -c -fmessage-length=0 -o "src\\test.o" "..\\src\\test.cpp" 
g++ -Wl,--gc-sections,-Map=output.map,--print-gc-sections -o test.exe "src\\test.o" 
size --format=berkeley test.exe 
   text    data     bss     dec     hex filename
  36424    2476    2608   41508    a224 test.exe

现在,如果我完全注释掉unused_function()并重新构建,size命令报告如下:
text    data     bss     dec     hex filename
36388    2476    2608   41472    a200 test.exe

我原本以为未使用的函数会被丢弃,因此文本大小不变,但显然情况并非如此。我是否遗漏了某个命令行选项或是我对GCC内部运作的无知所致?
这只是一个示例,用来展示我的问题。我正在使用一些第三方库进行各种功能,并且我的目标是确保将我使用的库部分从代码中删除。

1
在编译阶段,由于无法确定是否使用,它们不会被移除。而在链接阶段,您没有定义任何优化。 - Eugene Sh.
1
我在Linux上进行了测试 - gcc正确地删除了未使用的部分。你尝试过使用objdump来验证该部分是否确实存在吗?大小并不是非常相关。 - SergeyA
1
@YSC 谢谢你的建议。我可以看到 static 可以解决这个问题,但如果我要包括第三方库,我不想一直去修改它们里面的所有内容。那我只需要将我使用的所有库都放进一个命名空间里吗? - CodingHero
1
@CodingHero 请参考https://dev59.com/XGjWa4cB1Zd3GeqPrYIR,目前mingw似乎不支持此功能(虽然有一个补丁)。 - nos
2
你尝试过使用-Os(优化大小)进行编译/链接吗? - Ken P
显示剩余11条评论
1个回答

0

未使用的函数可能会被稍后链接的库所需。例如,一个内存分配接口由一个不想限制用户如何管理内存的库公开。

我们期望链接器在优化步骤中删除这些内容(尽管我遇到过相关问题,链接器无法删除所有这类调用的残留物)。


我理解为什么编译器会保留函数,但不理解链接器为什么要这样做。在这个例子中,没有其他库,但这些函数仍然没有被删除。根据上述评论,在这种特殊情况下,这是MinGW的一个bug。 - CodingHero
这就是我在快要睡着时匆匆浏览问题的下场。 - tletnes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接