mercredi 17 mai 2017

C++ MSVC/GCC/Clang compilers bug

I discovered what appears to be a mind breaking bug in the 3 compilers from the title. The following code compiles with the latest versions of all three compilers using both the c++11 and c++14 standards, even though it really shouldn't as the "visit_detail" function is not visible to "main".

#include <utility>
#include <iostream>
#include <type_traits>



namespace bug
{
    using namespace std;
    using size_t = unsigned long long;



    namespace detail
    {
        struct visit_stop_t {};
        constexpr bug::detail::visit_stop_t visit_stop = bug::detail::visit_stop_t();



        template <typename Visitor, typename First, typename... Tail>
        void visit_detail(Visitor&& vis, First&& first, Tail&&... tail)
        {
            // code, not necessairy to recreate bug
        }
    }


    template <typename Visitor, typename... Variants>
    void visit(Visitor&& vis, Variants&&... vars)
    {
        bug::detail::visit_detail(bug::forward<Visitor>(vis), bug::forward<Variants>(vars)..., bug::detail::visit_stop);
    }

    template <typename Visitor>
    void visit(Visitor&& vis) = delete;
}

using namespace bug;



// dummy variant, used to test the code
// code is never actually used in this version
template <typename... T>
struct variant
{
    static constexpr bug::size_t size() noexcept { return sizeof...(T); }


    constexpr variant(int) noexcept {}

    template <bug::size_t I>
    constexpr int get() const noexcept { return 5; }
};

// simple example visitor
// code is never actually used in this version
struct visitor
{
    int operator()(int x) { std::cout << x << std::endl; return x; }
    double operator()(double x) { std::cout << x << std::endl; return x; }
};



int main()
{
    visitor vis;
    variant<int, double> var = 5;

    // should throw compiler error:
    visit_detail(vis, var, bug::detail::visit_stop);


    std::cout << "Press enter to continue . . . ";
    std::getchar();
    return 0;
}

Aucun commentaire:

Enregistrer un commentaire