You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何-Wl,--entry参数在gcc中生效,在g++中却无效?

G++指定自定义入口点无效的原因及解决方法

环境与问题现象

当前环境为WSL1 + Ubuntu 20.04.5,使用GCC和G++ 9.4.0。尝试通过-Wl,--entry=foo参数指定自定义入口函数时,该操作在GCC中有效,但在G++中无效:

示例代码src/main.c如下:

#include <stdlib.h>
#include <stdio.h>

int main()
{
    printf("Entering %s:%s\n", __FILE__, __func__);
    return 0;
}

int not_main()
{
    printf("Entering %s:%s\n", __FILE__, __func__);
    exit(0); // 必须调用exit,否则会触发段错误
}
  • 使用GCC编译:gcc -Wl,--entry=not_main -o entry.o src/main.c,程序输出Entering src/main.c:not_main,符合预期。
  • 使用G++编译:g++ -Wl,--entry=not_main -o entry.o src/main.c,链接器提示/usr/bin/ld: warning: cannot find entry symbol not_main; defaulting to 0000000000001080,程序默认从main()启动,输出Entering src/main.c:main。

原因分析

G即使编译.c后缀的文件,也会默认按照C的规则处理代码,其中关键的一点是C++的名称修饰(Name Mangling):C++会将函数名编码成包含参数类型信息的符号名,以支持函数重载。而GCC编译C代码时使用的是C语言的命名规则,不会对函数名进行修饰。

所以当用G++编译时,not_main()会被修饰成类似_Z8not_mainv的符号名,而链接器通过--entry=not_main寻找的是未修饰的原始名称,自然找不到对应的符号,只能默认使用main()作为入口。

解决方法

方法1:强制函数使用C语言命名规则

在代码中用extern "C"声明目标入口函数,告诉编译器不要对该函数进行C++名称修饰:

#include <stdlib.h>
#include <stdio.h>

int main()
{
    printf("Entering %s:%s\n", __FILE__, __func__);
    return 0;
}

extern "C" int not_main()
{
    printf("Entering %s:%s\n", __FILE__, __func__);
    exit(0);
}

之后再用g++ -Wl,--entry=not_main -o entry.o src/main.c编译即可生效。

方法2:使用修饰后的符号名作为入口参数

先通过nm命令查看编译后的目标文件中的符号名:

g++ -c src/main.c -o temp.o
nm temp.o | grep not_main

会输出类似0000000000000000 T _Z8not_mainv的结果,然后用这个修饰后的名称作为入口参数:

g++ -Wl,--entry=_Z8not_mainv -o entry.o src/main.c

方法3:编译C代码直接使用GCC

如果你的代码本身是纯C代码,不需要C++特性,直接使用GCC编译即可避免名称修饰的问题,这也是最直接的解决方案。

内容的提问来源于stack exchange,提问作者RoGuinart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 18:20:32