Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gcc segfault on compiling nested parameter pack code

Tags:

c++

c++11

I was trying to write a code (using mingw32 gcc4.8.1 as of Jan 2014) involving two parameter packs Args1... and Args2.... I learned here (http://en.cppreference.com/w/cpp/language/parameter_pack) that I need a nested class for such. Args1... and Args2... are same lengths (,and ultimately I hope to deduce Args2... from Args1...). Sometimes they can be even the same type. So I wanted to write a shorthand using statement for this trivial case as a start:

template <typename R, typename ...Args>
using zip_t = zip<R, Args...>::with<Args...>;

However, gcc generates a segment fault when compiling this statement. Can anyone please explain if I did something wrong or is this a gcc bug?

g++ -std=c++11 -I..  testUsing.cpp
testUsing.cpp: In substitution of 'template<class R, class ... Args> using zip_t = zip<R, Args1 ...>::with<Args ...> [with R = A; Args = {}]':
testUsing.cpp:19:15:   required from here
testUsing.cpp:16:45: internal compiler error: Segmentation fault
 using zip_t = zip<R, Args...>::with<Args...>;
                                             ^

The minimal code is below: (adapted from http://en.cppreference.com/w/cpp/language/parameter_pack)

template<typename...> struct Tuple {};
template<typename T1, typename T2> struct Pair {};

template<class R,class ...Args1>  struct zip {
    template<class ...Args2> struct with {
        R flag;
        typedef Tuple<Pair<Args1, Args2>...> type;
        //Pair<Args1, Args2>... is the pack expansion, Pair<Args1, Args2> is the pattern
    };
};

typedef zip<bool,short, int>::with<unsigned short, unsigned>::type T1;
T1 make_zip1(bool) {return T1();}

template <typename R, typename ...Args>
using zip_t = zip<R, Args...>::with<Args...>;

template<typename A>
static zip_t<A>::type make_zip(A) {
  return zip_t<A>::type{};
}


//test code
int main() { return 0; }
like image 933
thor Avatar asked Nov 10 '22 14:11

thor


1 Answers

It surely a g++ bug. But your code isn't correct.

template <typename R, typename ...Args>
//using zip_t = zip<R, Args...>::with<Args...>;
using zip_t = typename zip<R, Args...>::template with<Args...>;

The problem is that, you missed two keywords, one typename, and one template.

If you add either template or typename but missed the other, gcc won't core segment fault. Clang will be better than gcc and it will tell you that you missed typename keyword or template keyword.

However, if you missed both, gcc will seg fault, and clang will tell you an error that you missed typename, but it won't tell you that you missed template.

like image 51
user534498 Avatar answered Nov 14 '22 22:11

user534498