This simple program
#include <cstdio>
#include <string>
int main() { std::printf("%s\n", std::to_string(3.14).c_str()); }
fails to compile with LTO in the latest version of gcc (and also in older versions), when using OpenOSC 1.0.7.
$ g++ --version
g++ (GCC) 15.1.1 20250521 (Red Hat 15.1.1-2)
Copyright (C) 2025 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ -O2 -flto -o test test.cpp -include /usr/local/include/openosc.h
/usr/local/include/openosc_redirect_map.h: In function '__to_xstring.constprop':
/usr/local/include/openosc_redirect_map.h:601:1: error: inlining failed in call to 'always_inline' 'vsnprintf': function body can be overwritten at link time
601 | __NTH (vsnprintf (char *__restrict __pass_objsize1 dst, size_t len, const char *__restrict fmt, va_list ap))
| ^
/usr/include/c++/15/ext/string_conversions.h:115:32: note: called from here
115 | const int __len = __convf(__s, __n, __fmt, __args);
| ^
lto-wrapper: fatal error: g++ returned 1 exit status
compilation terminated.
/usr/sbin/ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status
The problem seems to be that, according to the always_inline documentation,
Failure to inline such a function is diagnosed as an error. Note that if such a function is called indirectly the compiler may or may not inline it depending on optimization level and a failure to inline an indirect call may or may not be diagnosed.
And std::to_string in libstdc++ is implemented via a helper template that takes a pointer to vsnprint. The template is here.
Since vsnprintf is called indirectly, always_inline may fail.
You could argue the same problem applies to _FORTIFY_SOURCE but, since its implementation is way simpler, the inliner seems to be happier to inline it.
This simple program
fails to compile with LTO in the latest version of gcc (and also in older versions), when using OpenOSC 1.0.7.
The problem seems to be that, according to the always_inline documentation,
And std::to_string in libstdc++ is implemented via a helper template that takes a pointer to vsnprint. The template is here.
Since vsnprintf is called indirectly, always_inline may fail.
You could argue the same problem applies to _FORTIFY_SOURCE but, since its implementation is way simpler, the inliner seems to be happier to inline it.