递归联合中的链接器错误

时间:2015-11-26 18:55:23

标签: c++ clang linker-errors c++14 debug-symbols

考虑到一个过时的简化代码(我不知道如何减少它):

#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;
}

LIVE EXAMPLE

它的作用是通过递归union传播类型特征,以便在递归深度的某处使用它们。

目前,代码提供了链接器错误:

/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)

但如果我取消注释感叹号标记的行,则liker错误不再存在。这很奇怪,因为这样做我开始使用更多的符号,然后。 | c++filt -t无法解除这些符号,我无法推断出错了什么。是clang(版本3.7.0)错误还是ld(GNU ld v2.22)错误或其他什么?一般如何检测此类错误的来源?你使用哪些工具?

0 个答案:

没有答案