为什么所有的C++;编译器崩溃或挂起此代码? < >下面的代码位在我测试的每个C++编译器编译时:崩溃或挂起,直到内存耗尽: #include <tuple> template<class... Ts> auto f(Ts... ts){ return f(std::make_tuple(ts...)); } auto a = f(); #包括 模板 自动f(Ts…Ts){ 返回f(std::make_tuple(ts…); } 自动a=f();
在GCC、Clang、MSVC、icc、ELLCC的各种版本上进行测试:为什么所有的C++;编译器崩溃或挂起此代码? < >下面的代码位在我测试的每个C++编译器编译时:崩溃或挂起,直到内存耗尽: #include <tuple> template<class... Ts> auto f(Ts... ts){ return f(std::make_tuple(ts...)); } auto a = f(); #包括 模板 自动f(Ts…Ts){ 返回f(std::make_tuple(ts…); } 自动a=f();,c++,templates,c++14,c++17,C++,Templates,C++14,C++17,在GCC、Clang、MSVC、icc、ELLCC的各种版本上进行测试: 我的问题是,为什么这些编译器实现的模板深度限制或类似的安全性没有抓住这一点?我找到了一些导致编译器挂起的代码示例,但似乎我能找到的所有问题都已得到修复,因为它已成为限制模板实例化深度的标准 我应该注意到,这不是make\u tuple所独有的,它适用于tie,forward\u as\u tuple。。。等等 作为警告,如果您试图在本地编译此文件,请确保使用类似于ulimit的方法来确保编译器不会耗尽内存。我在处理这个
我的问题是,为什么这些编译器实现的模板深度限制或类似的安全性没有抓住这一点?我找到了一些导致编译器挂起的代码示例,但似乎我能找到的所有问题都已得到修复,因为它已成为限制模板实例化深度的标准 我应该注意到,这不是
make\u tuple
所独有的,它适用于tie
,forward\u as\u tuple
。。。等等
作为警告,如果您试图在本地编译此文件,请确保使用类似于
ulimit
的方法来确保编译器不会耗尽内存。我在处理这个问题时不得不硬重启过几次。GCC没有实现所有可能的可变函数模板递归检测方法(或者可能没有),可能是由于评论中提出的问题的变化
OP示例与2014年的未解决问题非常相似(相同?)。看起来,防止此类错误,或者实际上——防止此类错误在开发人员的工作站上蔓延——对GCC开发人员来说并不是一个优先事项。顺便说一句,bug报告中的示例程序滥用内存的速度比OP快得多:有了800MB的数据限制,我可以让OP执行150多个模板实例化,而bug报告中的程序在不到20分钟后就耗尽内存
这两个程序也会使clang崩溃,所以我猜clang开发人员的优先级类似。他们确实有深度限制,但在这种情况下,所需的内存可能会随着深度的增加而增加,因为您将在第N级使用std::tuple(N层)。“如果您试图在本地编译此文件,请确保使用类似ulimit的东西”或use(gcc)手动标记
-ftemplate depth=X
。这有点像是问为什么编译器不能解决暂停问题。@Barry,是吗?在这种情况下,提供了大量的信息来知道停止是不可能的。@JeffreyCash:“是吗?”是的,是的。在许多情况下,您可以确定在许多语言中是否可以暂停,但这并不意味着编译器应该尝试这样做。仅仅因为您可以看到存在无限递归,并不意味着我们应该让编译器尝试这样做。