GCC和Clang等编译器允许在没有C++标准库的情况下编译C++程序,例如使用-nostdlib命令行标志.似乎这种情况经常无法与您联系,例如:
void f() noexcept { throw 42; }
int main() { f(); }
Run Code Online (Sandbox Code Playgroud)
通常无法链接由于像未定义的符号__cxa_allocate_exception,typeinfo for int,__cxa_throw,__gxx_personality_v0,__clang_call_terminate,__cxa_begin_catch,std::terminate()等.
即使是简单的
int main() {}
Run Code Online (Sandbox Code Playgroud)
无法链接
ld:警告:找不到输入符号
_start; 默认为0000000000400120
并在执行时被操作系统杀死.使用-c编译器仍会运行显式失败的链接器:
LD:错误
mytest(.eh_frame); 不会.eh_frame_hdr创建任何表.
在不使用和链接到标准库的情况下编程和编译C++应用程序或库是否是一个现实的目标?如何在Linux上使用GCC或Clang编译我的代码?没有标准库,哪些核心语言功能无法使用?
小智 21
您基本上可以在osdev.org上找到所有问题的答案,但无论如何我都会给出一个简短的总结.
当你给GCC时-nostdlib,你说"没有启动或库文件".这包括:
crti.o,crtbegin.o,crtend.o和crtn.o.通常,内核开发人员只关心实现crti.o和crtend.o让GCC提供crtbegin.o并crtend.o传递-print-file-name=给链接器.一般来说,这些都只是存根包括.init与.fini分别,留有余地GCC推去的内容crtbegin.o,并crtend.o分别.这些文件是调用全局构造函数/析构函数所必需的.libgcc("低级运行时库"(-lgcc),因为即使您通过-nostdlibGCC也会在您使用它时发出对其函数的调用,导致无法理解的链接错误,看似没有理由.即使是你正在实现/移植一个C库.libstdc++不,但通常内核开发人员需要它.移植C库然后从头开始实现C++标准库是一项非常困难的任务.既然你只想摆脱"标准库",但保留libc(在Linux系统上),你实际上只用C库编写C++.当然,这对你没有任何不妥,但你最终我没有看到这一点,除非你打算开发一个内核.
必读:
OSDev的C++页面 - 如果你真的关心RTTI /异常支持,它的实现比听起来更烦人.通常人们只是通过-fno-rtti或者-fno-exceptions然后担心它或者根本不担心.
"标准"是用词不当.在这种情况下,它并不意味着"C++标准定义的库(函数,类等)",而是"通常的库和对象集合(某种格式的编译文件)gcc默认链接".其中一些是大多数甚至所有程序运行所必需的.
如果您使用此标志,则您有责任提供任何缺少的功能.有几种方法可以这样做:
| 归档时间: |
|
| 查看次数: |
4150 次 |
| 最近记录: |