Compilers such as GCC and Clang allow to compile C++ programs without the C++ standard library, e.g. using the -nostdlib
command line flag. It seems that such often fail to link thou, for example:
void f() noexcept { throw 42; }
int main() { f(); }
Usually fails to link due to undefined symbols like __cxa_allocate_exception
, typeinfo for int
, __cxa_throw
, __gxx_personality_v0
, __clang_call_terminate
, __cxa_begin_catch
, std::terminate()
etc.
Even a simple
int main() {}
Fails to link with
ld: warning: cannot find entry symbol
_start
; defaulting to 0000000000400120
and is killed by the OS upon execution. Using -c
the compiler still runs the linker which blatantly fails with:
ld: error in
mytest
(.eh_frame
); no.eh_frame_hdr
table will be created.
Is it a realistic goal to program and compile C++ applications or libraries without using and linking to the standard library? How can I compile my code using GCC or Clang on Linux? What core language features would one be unable to use without the standard library?
The C++ Standard Library provides several generic containers, functions to use and manipulate these containers, function objects, generic strings and streams (including interactive and file I/O), support for some language features, and functions for everyday tasks such as finding the square root of a number.
The C++ Standard Library is a collection of classes, functions, macros, constants etc which have been written in the core C++ language.
Today at CppCon 2019, we (the MSVC team) announced that we're releasing our implementation of the C++ Standard Library (also known as the STL) as open source.
You will basically find all of your questions answered at osdev.org, but I'll give a brief summary anyway.
When you give GCC -nostdlib
, you are saying "no startup or library files". This includes:
crti.o
, crtbegin.o
, crtend.o
and crtn.o
. Generally kernel developers only care about implementing crti.o
and crtend.o
and let GCC supply crtbegin.o
and crtend.o
by passing -print-file-name=
to the linker. Generally these are just stubs that consist of .init
and .fini
respectively, leaving room for GCC to shove the contents of crtbegin.o
and crtend.o
respectively. These files are necessary for calling global constructors/destructors. libgcc
(the "low-level runtime library" (-lgcc
) because even if you pass -nostdlib
GCC will emit calls to its functions whenever you use it, leading to inexplicable linking errors for seemingly no reason. This is the case even when you're implementing/porting a C library.libstdc++
no, but typically kernel developers want it. Porting a C library then implementing the C++ standard library from scratch is an extremely difficult task.Since you only want to get rid of the "standard library", but keeping libc (on a Linux system) you're essentially programming C++ with just a C library. Of course, there's nothing wrong with this and you do you, but ultimately I don't see the point unless you plan on developing a kernel.
Required reading:
OSDev's C++ page - If you really care about RTTI/exception support, it's more annoying to implement than it sounds. Typically people just pass -fno-rtti
or -fno-exceptions
and then worry about it down the line or not at all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With