https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98861
--- Comment #29 from cqwrteur <unlvsur at live dot com> --- (In reply to Jakub Jelinek from comment #23) > And memcpy must be provided as documented in the GCC documentation: > Most of the compiler support routines used by GCC are present in > @file{libgcc}, but there are a few exceptions. GCC requires the > freestanding environment provide @code{memcpy}, @code{memmove}, > @code{memset} and @code{memcmp}. > Finally, if @code{__builtin_trap} is used, and the target does > not implement the @code{trap} pattern, then GCC emits a call > to @code{abort}. I am sure I did not understand anything wrong. The rule is simple, if you use gcc, you must use libgcc. libgcc provides those facilities. https://wiki.osdev.org/Libgcc __builtin_trap() is always faster than std::terminate(), even it actually emits a call to std::abort(), because std::terminate() requires atomic to sync the terminate_handler. The problem with std::terminate() is that it does not work like operator new where it is weak alias. You still get bloat and dependency to std::abort() even you are using set_terminate_handle(). if we are using __builtin_trap() on platforms like x86_64, they emit ud instructions and use that to terminate is fast and avoid dependency on libc, (particularly we mean glibc here.)