1

我正在开发一个操作系统内核作为一种爱好,并且我已经有一个库可以在托管和独立环境中替换标准库。自然地,它提供了进行必要设置和调用的入口点main()

main()在托管环境中,声明的签名和实际main()定义中的签名是否不完全匹配似乎无关紧要。但是,一旦我添加了-ffreestanding编译标志,链接器就无法再解析这样的引用。请参阅下面的最小示例:

启动.cpp

int main(int argc, char *argv[], char *envp[]);

extern "C" void _start()
{
    main(0, nullptr, nullptr);
}

主文件

int main()
{
    return 0;
}

命令行:

clang++-6.0 -nostdlib -ffreestanding start.cpp main.cpp

由于 GCC 7.3.0 成功编译了此示例,因此这种行为似乎是 Clang 特有的。

我的问题是如何允许上述示例并在一般情况下工作,以及我遇到的问题是否是 Clang 错误。


更新1:

原来,解决这个问题的方法是添加__attribute__((weak))main(). 但是,如果有人可以更详细地解释这通常如何与main().

更新 2:

显然,将其标记main()为弱符号可以在没有链接的情况下进行链接main(),这显然不是它通常的工作方式(考虑到 SO 上的所有其他“未定义对主要的引用”问题)。那么 ifmain()通常不是一个弱符号,它是如何真正起作用的呢?

更新 3:

事实证明,弱符号根本不是解决方案,因为与它一起使用时只会隐藏从未解决且根本不调用实际符号-ffreestanding的事实。但是在托管环境中,它仍然像往常一样被调用。这似乎越来越像一个 Clang 错误。int main(int argc, char *argv[], char *envp[])int main()_start()

4

0 回答 0