[cfe-dev] C++11 ABI Compatibility and Static Initialization
Erik Schnetter
schnetter at gmail.com
Wed Apr 9 05:56:14 PDT 2014
On Apr 9, 2014, at 1:43 , Kevin Locke <kevin at kevinlocke.name> wrote:
> On Tue, 2014-04-08 at 18:50 -0400, Erik Schnetter wrote:
>> On Apr 7, 2014, at 18:11 , Kevin Locke <kevin at kevinlocke.name> wrote:
>>> Now that I have identified that the issue is C++11 ABI compatibility,
>>> I can easily avoid the issue on my systems. However, I have brought
>>> it to your attention in the hopes that it can either made easier to
>>> identify or the compatibility can be improved to save future users the
>>> effort spent debugging to identify the same issue.
>>
>> From my reading of the Boost sources, it seems that Boost determines
>> at compile time whether constexpr is available, and uses it if so.
>> This means that Boost consists of different C++ code depending on
>> whether -std=c++11 is used or not. I would assume that this means
>> that the resulting object code should not be expected to work.
>>
>> My initial reaction is that this is an error in Boost (which could
>> make this distinction at configuration time instead of at compile
>> time), or that Boost should at least detect this problem and abort
>> with an error. Of course, if clang could detect this
>> incompatibility, this would also be good.
>
> Hi Erik and Mehdi,
>
> Thanks for considering the issue! You are quite right about the
> conditional use of constexpr and Boost's decision not to pursue binary
> compatibility across C++ dialects. A bug report to boost to make the
> error more easily identifiable may be warranted, depending on your
> thoughts on the root of the issue, discussed below.
>
> I wonder if Boost may have been a bit of a red herring as to whether
> there is a clang issue (or potential improvement) for this case. So
> I've worked out a more minimal example which does not rely on Boost:
>
> -8<--libawesome.hpp---------------------------------------------------
> #if __has_feature(cxx_constexpr)
> #define CONSTEXPR_OR_CONST constexpr
> #else
> #define CONSTEXPR_OR_CONST const
> #endif
>
> inline double dummy(const double* num) {
> return 1.0L;
> }
>
> inline CONSTEXPR_OR_CONST double maybe_constexpr(double v)
> {
> return v;
> }
>
> template <class Awesome>
> struct awesome_initializer
> {
> struct init
> {
> init()
> {
> Awesome::calc_stuff();
> }
> void force_instantiate()const{}
> };
> static const init initializer;
> static void force_instantiate()
> {
> initializer.force_instantiate();
> }
> };
> template <class Awesome>
> typename awesome_initializer<Awesome>::init const awesome_initializer<Awesome>::initializer;
>
> struct awesome
> {
> static double calc_stuff()
> {
> awesome_initializer<awesome>::force_instantiate();
> static const double num[1] = {
> maybe_constexpr(1.0)
> };
> return dummy(num);
> }
> };
> -8<--libawesome.hpp---------------------------------------------------
>
> -8<--libcrash11.cpp---------------------------------------------------
> #include "libawesome.hpp"
>
> double libfunc() {
> return awesome::calc_stuff();
> }
> -8<--libcrash11.cpp---------------------------------------------------
>
> -8<--crash11.cpp------------------------------------------------------
> #include "libawesome.hpp"
>
> int main(int,char**) {
> awesome::calc_stuff();
> return 0;
> }
> -8<--crash11.cpp------------------------------------------------------
>
> As before, they can be compiled as follows:
> clang++ -dynamiclib -o libcrash11.dylib libcrash11.cpp
> clang++ -std=c++11 -L. -lcrash11 -o crash11 crash11.cpp
>
> Also as before, executing crash11 will result in an EXC_BAD_ACCESS
> error and program crash.
>
> It is worth noting that the error can be caused by a header-only
> library shared (possibly as an internal implementation detail) by the
> program and a library on which it depends, even when neither the
> program nor library use any C++11 features. Also note that only
> fundamental types are passed between the program and the library (in
> the example, only the double returned by the library function), making
> the error all the more unexpected.
>
> Is there anything which can be done to improve the situation in cases
> like this, or is some hairy static initializer debugging just the
> price that everyone has to pay for making this sort of mistake?
I would have hoped that name mangling catches this problem via a linker error.
-erik
--
Erik Schnetter <schnetter at gmail.com>
http://www.perimeterinstitute.ca/personal/eschnetter/
My email is as private as my paper mail. I therefore support encrypting
and signing email messages. Get my PGP key from http://pgp.mit.edu/.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 203 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140409/eb1e6d9b/attachment.sig>
More information about the cfe-dev
mailing list