What is the cause of type instability?

Today I was debugging a failed clang build. This construction has essentially broken down because it is_default_constructibleis rated as false. I reduced the problem to a minimal case after several hours of debasing the problem:

#include <type_traits>
#include <string>

namespace A {
    // This has been extracted from an old (outdated(?))
    // implementation of an optional type

    struct empty_t {};

    template<class T>
    struct o
    {
    public:
        template<class... U,
                 typename std::enable_if<
                     std::is_constructible<T, U...>::value,
                     bool
                     >::type = false
                 >
        o(empty_t, U&&... u) { }
    };

}

struct B
{
    struct Foo
    {
        //Foo () {};   // uncomment this line and it works
        bool x = true; // comment this line and it works
    };

    std::string c; // comment this line and it works, also change to int
    A::o<Foo> r;   // comment this line and it works

    static const bool b;
};

static_assert(
    std::is_default_constructible<B::Foo>::value,
    "not constructible!");

The above example compiles with g ++ 6.3 and 7.0. It fails with clang ++ 4.0.0 and 3.9.1 - the static statement fails only in this very specific construction, but it still broke our assembly. As you can try for yourself, some minimal changes fix the problem (for example, by commenting on one of the specified lines). The result looks somewhat arbitrary.

, , , clang undefined. ?

, : - - , , Foo ?

, - () ++ , .

+6
1

, (.. ). (.. ), .

, Foo B.

0

All Articles