Search code examples
c++gcccompiler-errorsvariadic-templatescompiler-flags

GCC anonymous is uninitialised


I'm trying to create something similar to std::tuple, a sort of compile-time list using variadic templates and recursive inheritance as shown in the implementation below.

My problem would be that although the implementation shown below works fine on msvc, clang and icc ConstExprList::Get always returns 0 on gcc(trunk version).

If compile the code with -Wall -Werror options enabled, gcc throws the following error:

anonymous is used uninitialized in this function [-Werror=uninitialized].

Note that with optimizations disabled the error does not occur.

Is this a bug in the gcc implementation or am missing something?

#include <type_traits>

template <typename... Args>
class ConstExprList;

template <typename Head, typename... Tail>
class ConstExprList<Head, Tail...> : public ConstExprList<Tail...>
{
public:
    ConstExprList(const Head& head, const Tail&... tail) : ConstExprList<Tail...>(tail...),  m_head(head) {}

    template <std::size_t Idx>
    inline typename std::enable_if<Idx == 0, Head>::type Get(void) const noexcept
    {
        return m_head;
    }

    template <std::size_t Idx>
    inline typename std::enable_if<Idx != 0, Head>::type Get(void) const noexcept
    {
        return ConstExprList<Tail...>::template Get<Idx - 1>();
    }

private:
    const Head& m_head;
};

template <typename Head>
class ConstExprList<Head>
{
public:
    ConstExprList(const Head& head) : m_head(head) {}

    template <std::size_t Idx>
    inline auto Get(void) const noexcept
    {
        static_assert(Idx == 0, "Index out of range");
        return m_head;
    }

private:
    const Head& m_head;
};

int main(void)
{
    ConstExprList<int, int> l(7, 3);

    return l.Get<0>();
}

Solution

  • The warning is misleading but points out a real problem. m_head is a reference initialised to a temporary. This is not one of the contexts that will cause the temporary's lifetime to be extended, so your references are left dangling.