C++ 递归联合中的链接器错误

C++ 递归联合中的链接器错误,c++,clang,linker-errors,c++14,debug-symbols,C++,Clang,Linker Errors,C++14,Debug Symbols,给出一个非常简单的代码(我不知道如何进一步简化): 但是如果我取消注释用感叹号标记的行,那么liker错误就不存在了。这很奇怪,因为这样做我开始使用更多的符号,然后以前| c++过滤器-t不能要求使用这些符号,我无法推断出哪里出了问题。它是clang(3.7.0版)bug还是ld(GNU ld v2.22)bug还是其他什么?一般来说,如何检测此类错误的来源?您使用哪些工具?尝试将这一点减少到显示问题的最小代码可能会有所帮助。它看起来确实像一个编译器错误。一个简单的例子是添加一个bug报告。如果

给出一个非常简单的代码(我不知道如何进一步简化):


但是如果我取消注释用感叹号标记的行,那么liker错误就不存在了。这很奇怪,因为这样做我开始使用更多的符号,然后以前<代码>| c++过滤器-t不能要求使用这些符号,我无法推断出哪里出了问题。它是
clang
(3.7.0版)bug还是
ld
(GNU ld v2.22)bug还是其他什么?一般来说,如何检测此类错误的来源?您使用哪些工具?

尝试将这一点减少到显示问题的最小代码可能会有所帮助。它看起来确实像一个编译器错误。一个简单的例子是添加一个bug报告。如果我删除你漂亮的打印宏,效果会很好:p另外,如果你添加另一个前导下划线,符号也可以被删除。它们指的是
U
的三个不同实例的析构函数。我从源代码中构建的clang 3.8.0也可以不做任何更改。更正,从主代码中提取并重建clang 3.8.0,现在我得到了相同的未解析符号,因此它似乎没有解析。
#include <type_traits>
#include <iostream>

#include <cstdlib>

#define PP { std::cout << __PRETTY_FUNCTION__ << std::endl; }

struct descriptor
{
    std::size_t const s;
    bool const * c;
    bool const * d;
};

template< descriptor const & x, bool c, bool d, typename ...types >
union U;

template< descriptor const & x, bool c, bool d >
union U< x, c, d >
{
    static_assert(c);
    static_assert(d);

    U() PP
    ~U() PP
};

template< descriptor const & x, bool c, bool d, typename first, typename ...rest >
union U< x, c, d, first, rest... > // specialize against c and/or d values
{
    static constexpr std::size_t s = x.s - sizeof...(rest);
    using tail = U< x, x.c[s], x.d[s], rest... >;

    first head_;
    tail tail_{};

    U() PP
    ~U() { PP; /*tail_.~tail();*/ } // !!!!!!!
};

template< typename ...types >
struct V
{
    static constexpr bool c[sizeof...(types) + 1] = {std::is_trivially_constructible< types >{}..., true};
    static constexpr bool d[sizeof...(types) + 1] = {std::is_trivially_destructible< types >{}..., true};
    static constexpr descriptor x{sizeof...(types), c, d};
    U< x, x.c[0], x.d[0], types... > storage_;

    V() PP
    ~V() PP
};

template< typename ...types >
constexpr bool V< types... >::c[sizeof...(types) + 1];
template< typename ...types >
constexpr bool V< types... >::d[sizeof...(types) + 1];
template< typename ...types >
constexpr descriptor V< types... >::x;

int
main()
{
    struct S { S() { ; } ~S() { ; } };
    V< int, S, double > v;
    (void)v;
    S s;
    (void)s;
    return EXIT_SUCCESS;
}
/tmp/main-ecd8fb.o: In function `main':
main.cpp:(.text+0x2fa): undefined reference to `_ZN1UIL_ZN1VIJiZ4mainE1SdEE1xEELb1ELb1EJEED1Ev'
main.cpp:(.text+0x318): undefined reference to `_ZN1UIL_ZN1VIJiZ4mainE1SdEE1xEELb1ELb1EJdEED1Ev'
main.cpp:(.text+0x336): undefined reference to `_ZN1UIL_ZN1VIJiZ4mainE1SdEE1xEELb0ELb0EJS1_dEED1Ev'
clang: error: linker command failed with exit code 1 (use -v to see invocation)