2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 <2020> 2021 2022 2023 2024 2025 | Index | 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 <2020> 2021 2022 2023 2024 2025 |
<== Date ==> | <== Thread ==> |
---|
Subject: | Re: ABI compatibility with different C++ standard versions |
From: | Ralph Lange via Core-talk <core-talk at aps.anl.gov> |
To: | EPICS Core Talk <core-talk at aps.anl.gov> |
Date: | Thu, 8 Oct 2020 10:57:18 +0200 |
Hi Michael,
Thanks for making the following comment on an Asyn pull request [1]
which pointed me to an aspect I hadn't considered, yet:
> Be aware that -std=* can effect ABI.
Thanks for linking to [2] which provides further information on the
topic. However, after reading this page my understanding is that -std=*
does _not_ affect ABI (only the _GLIBCXX_USE_CXX11_ABI macro does).
According to my understanding this means for us:
1. We can compile old.cpp with -std=c++03 and new.cpp with -std=c++11
and then link them together without any issues even when using GCC 5.1+.
This means we can suppress deprecation warnings in one source file of
our code base (-std=c++03) while leveraging a more modern standards
version in other files (-std=c++11) - even if the resulting object
files/libraries are linked together later.
2. Assuming we're not messing with _GLIBCXX_USE_CXX11_ABI, linking a
library/object file compiled with GCC <5 to a library/object file
compiled with GCC 5+ might fail. Developers can fix this by either
rebuilding EPICS Base + all support libraries + all IOCs after upgrading
their compiler/standard library from GCC <5 to GCC 5+ or by using the
macro mentioned above.
I ran a quick test with the attached source code to verify that the same
symbol names are used:
$ g++ -std=c++03 string.cpp && nm a.out | c++filt | grep string | head -n 1
U std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >::basic_string(char
const*, std::allocator<char> const&)@@GLIBCXX_3.4.21
$ g++ -std=c++11 string.cpp && nm a.out | c++filt | grep string | head -n 1
U std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >::basic_string(char
const*, std::allocator<char> const&)@@GLIBCXX_3.4.21
In both cases the new std::__cxx11::basic_string is used while I see the
old std::basic_string symbol instead when compiling with
-D_GLIBCXX_USE_CXX_ABI=0. The mangled symbols are the same as well (not
shown here because they aren't pleasant to look at).
With this in mind I believe that as developers we can in fact control
the standards version without risking any ABI incompatibilities. Use of
the macro, however, should be left to the labs/users who are building
the code - although I believe most of them will simply chose to
recompile their code instead.
Cheers,
Martin
[1] https://github.com/epics-modules/asyn/pull/125#issuecomment-699658823
[2] https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
--
Martin Konrad
Facility for Rare Isotope Beams
Michigan State University
640 South Shaw Lane
East Lansing, MI 48824-1321, USA
Tel. 517-908-7253
Email: konrad at frib.msu.edu