C++ VS是否可以警告可能的堆栈溢出异常?

C++ VS是否可以警告可能的堆栈溢出异常?,c++,visual-studio,stack-overflow,C++,Visual Studio,Stack Overflow,考虑以下代码(仅用于演示): #包括 int main() { 字符像素[4][1280][720];//大到足以在我的计算机上造成堆栈溢出 for(无符号整数i=0;i

考虑以下代码(仅用于演示):

#包括
int main()
{
字符像素[4][1280][720];//大到足以在我的计算机上造成堆栈溢出
for(无符号整数i=0;i<4;i++)
{
for(无符号整数j=0;j<1280;j++)
{
for(无符号整数k=0;k<720;k++)
{
像素[i][j][k]=i+j+k;
}
}
}
std::cout编译器几乎可以对任何事情发出警告,但在这种情况下,编译器很难给出真正有意义的警告

特别是,直到链接时才真正选择堆栈大小。编译器在链接器之前运行,因此它根本不可能知道在运行链接器时可能选择的堆栈大小。因此,如果编译器发出警告,它所能做的最好的事就是假设一些“合理的”将选择堆栈大小,并根据违反该大小发出警告

一个足够智能的链接器可能会发出这样的警告,但这需要相当多的智能。特别是,当链接器看到它时,堆栈分配看起来像(的机器代码表示):


链接器必须找到堆栈指针被操纵的每个位置,并检查所涉及的数字的大小以发出有意义的警告。要做到这一点,它基本上必须准确地找出什么是代码,什么是数据,然后反汇编并检查代码(但不是数据,它可能会分解成无意义的代码)。这可能都是可能的,但可能有点不平凡,当然也远远超出了链接器通常做或处理的范围。

在具有
/analyze
标志的版本中,它已经做了:

C:\>cl /EHsc /analyze stack.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

stack.cpp
c:\stack.cpp(3) : warning C6262: Function uses '3686412' bytes of stack:  exceeds /analyze:stacksize '16384'.  Consider moving some data to heap.
DDK/WDK附带的
prefast
工具会产生类似的警告


当然,这是一个非常简单的静态检查(如果函数的堆栈使用率高于某个阈值)。它不会尝试检测递归调用或通过调用链累计总静态使用量。

评估复杂代码以准确了解它在不执行它的情况下会做什么是圣杯之一。不要抱太大希望。你的意思类似于GCC
-Wstack usage=1234
?@Fanael我的意思是,如果数组的字节大小为bigger大于堆栈限制,此时堆栈溢出肯定会发生。因此它可能会就此发出警告。是的,似乎就是这样。​+1,当我打开大量SIMD对象的积极内联时,我总是遇到这种情况。我宁愿编译器在编译时警告我,而不是在运行时崩溃。理论上,这是可以做到的。我是在IBM System/38上为Pascal实现这样做的。问题是,您实际上必须抛出一个异常,这需要堆栈空间ndle,所以您必须“保留”这需要大量的堆栈。我发现,如果保留一半的堆栈用于异常处理,那么它实际上只起到了一半的作用,而且,在抛出异常之前,为应用程序提供更多的堆栈更有意义。我想知道是否有一个编译器选项可以在单个函数tion使用了过多的堆栈。因为我经常在几个级别的内联使编译器决定在堆栈上放入1000个SIMD值时破坏堆栈。@神秘:正如Andrew Medico指出的,
/analyze
标志基本上符合我第二段的建议:选择一个“合理的”大小,并在超出该值时发出警告。大小默认为16K,但如果您愿意,可以将其设置为其他大小,例如:
/analyze:stacksize 65535
,这将(显然足够)改为寻找64K。我可能会尝试类似1k的东西,看看它抱怨什么。最大的麻烦是编译器在运行时之前我都不知道它,却将大量内容插入递归函数。这种分析是有缺陷的,因为它忽略了合作的可能性。编译器可能会实际发出堆栈使用数据,例如,在一个单独的辅助文件中。链接器在读取此文件时,可以创建一个部分调用图,并确定已知调用图上的任何路径是否超过堆栈限制。挑战:循环-但这是我们理解的一种情况。即使只有一个变量,无限递归也确实会导致堆栈溢出。analyze不是仅在t中可用吗他>2000美元的版本?我相信以前的版本也是如此,但从2013年开始。
sub esp, 123456 ; or sub rsp, 123456 in 64-bit code.
C:\>cl /EHsc /analyze stack.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

stack.cpp
c:\stack.cpp(3) : warning C6262: Function uses '3686412' bytes of stack:  exceeds /analyze:stacksize '16384'.  Consider moving some data to heap.