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