MSVC 2019和2022编译器在c++17和c++20中编译相对较大的std::复杂数组时挂起并且不稳定



使用最新的c++ MSVC 2019和2022编译时,以下代码挂起

#include <complex>
// const int N = 10000; // about 3 secs
// const int N = 40000; // about 40 secs
const int N = 200000; // hangs (over 10 min)
//const int N = 2000000; // normal, 1 sec
std::complex<double> x[N];
int main()
{
for (size_t i = 0; i < 200; i++)
x[i] = std::complex<double>(1,2);
}

奇怪的是,它以不同的速度编译,如所示,包括更大的大小。看起来像个bug,我已经报告了。如果在相同大小的向量中工作良好。知道是什么引起的吗?值得关注的是,这可能会在其他地方弹出或产生错误的编译。

将变量移到main中,您将看到快速编译;但如果它在调试时崩溃,也不要惊慌。当前,您已经声明了一个巨大的静态对象,编译器很可能试图为它分配磁盘空间。评估最终生成的二进制文件(.exe文件)的大小。应该是10xN。您可能会发现编译优化开关会牺牲执行速度,以支持内存或可执行文件大小。这个大文件并不孤单。在生成最终二进制文件之前,有很多步骤需要处理一些更大的文件,包括object (.obj)文件。这个简单的(?)程序占用了千兆字节的存储空间。

编辑 :==============================

在某个阈值之后——我猜可以通过编译器开关来调整——编译器会为巨大的静态对象动态分配内存;然而,从程序员的角度来看,这仍然是一个静态对象。无论如何,如此巨大的对象不应该放在静态存储上,也不应该放在自动存储上。它们必须放在动态存储中;通过std::vectorstd::unique_ptr或其他智能对象:

std::vector<std::complex<double> >bigvec{bigN,0.0};
auto bigptr=std::make_unique<complex<double>[]>(bigN);

因为最终(不管怎样),巨大的对象将会增加初始化的运行时开销。我无法想象操作系统应该如何加载和运行一个GB的可执行文件;真让我毛骨悚然。

最新更新