编译嵌套参数包代码时,GCC出现段错误

5
我试图编写一段代码(使用mingw32 gcc4.8.1,截至2014年1月),涉及两个参数包Args1...Args2...。我在这里学到(http://en.cppreference.com/w/cpp/language/parameter_pack),我需要一个嵌套类来实现这样的操作。Args1...Args2...长度相同(最终我希望从Args1...推导出Args2...)。有时它们甚至可以是相同的类型。因此,我想先为这种微不足道的情况编写一个简写的using语句:
template <typename R, typename ...Args>
using zip_t = zip<R, Args...>::with<Args...>;

然而,当编译这个语句时,gcc会生成一个段错误。请问是否有人能解释一下我做错了什么或者这是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...>;
                                             ^

最简单的代码如下:(源自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; }

3
编译器中的分段错误总是编译器中的一个错误。 - bobah
可以在gcc 4.8.2上重现此问题。 - pmr
编译器绝不能因为所给的代码而崩溃...所以这肯定是一个bug。你可以尝试使用clang++,看看它是否有不同的表现。如果还没有的话,你可能想在gcc bugzilla上报告一个bug。 - Mats Petersson
谢谢,我已经根据此提交了一个错误报告http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59964。 - thor
谢谢,现在我知道我不是唯一一个使用GCC编译某些东西(在我的情况下是用模板元编程计算Mandelbrot分形图像)并导致GCC段错误的人。 - Manu343726
我记得曾经错误地编写了一个无限循环,导致编译时出现了段错误(如果我没记错的话)。因此,我想先询问一下,而不是向gcc开发人员发送虚假警报。 - thor
1个回答

1

这肯定是g++的一个bug。但是你的代码不正确。

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

问题在于,您错过了两个关键字,一个类型名称和一个模板。
如果您添加了模板或类型名称但遗漏了另一个,则gcc不会核心段错误。 Clang比gcc更好,它会告诉您错过了typename关键字或template关键字。
但是,如果您两个都错过了,gcc将seg fault,而clang将告诉您错过了typename的错误,但不会告诉您错过了template。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接