为什么所有 C++ 编译器都会因为这段代码而崩溃或挂起?

Jef*_*ash 10 c++ templates c++14 c++17

当我测试过的每个 C++ 编译器编译时,以下代码会崩溃或挂起,直到内存耗尽:

#include <tuple>

template<class... Ts>
auto f(Ts... ts){
  return f(std::make_tuple(ts...)); 
}

auto a = f();
Run Code Online (Sandbox Code Playgroud)

在各种版本的 GCC、Clang、MSVC、icc、ELLCC 上测试:https ://godbolt.org/z/cwqiZK


我的问题是为什么这不被模板深度限制或这些编译器实现的类似安全所捕获?我发现了一些代码示例,例如这个旧示例,会导致编译器挂起,但似乎我能找到的所有问题都已解决,因为它成为限制模板实例化深度的标准。

我要指出,这不是唯一的make_tuple,和工程tieforward_as_tuple...等等。


作为警告,如果您尝试在本地编译它,请务必使用类似的方法ulimit来确保编译器不会耗尽您的内存。在玩这个时,我不得不硬重启几次。

Gus*_*uss 1

GCC 没有实现所有可能的可变参数函数模板递归检测方法(或者可能没有?),可能是由于评论中提出的问题有所不同。

OP 示例看起来与2014 年尚未解决的GCC bug 59914非常相似(相同?)。看起来防止此类错误,或者实际上 - 防止此类错误在开发人员的工作站上爆炸 - 对于 GCC 开发人员来说并不是一个高度优先的事项。顺便说一句 - bug 中报告的示例程序滥用内存的速度比 OP 快得多:在 800MB 数据限制下,我可以让 OP 执行超过 150 个模板实例化,而 bug 报告中的程序在不到 20 个后就耗尽内存。

这两个程序也会导致 clang 崩溃,所以我猜 clang 开发人员有类似的优先事项。