VS可以警告可能的堆栈溢出异常吗?

Bor*_*der 8 c++ stack-overflow visual-studio

请考虑以下代码(用于演示目的):

#include <iostream>

int main()
{
    char pixels[4][1280][720]; // Big enough to cause a stack overflow on my machine
    for (unsigned int i = 0; i < 4; i++)
    {
        for (unsigned int j = 0; j < 1280; j++)
        {
            for (unsigned int k = 0; k < 720; k++)
            {
                pixels[i][j][k] = i + j + k;
            }
        }
    }

    std::cout << pixels[2][640][360];
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

根据这个问题的答案,最大堆栈大小由visual studio设置.

假设它可以警告用户潜在的堆栈溢出,我是否正确?(我自己尝试了这个并没有得到警告)

PS:我问的唯一原因是因为我看到很多关于SO的问题可以通过这样的警告来防止(是的,我知道不是每个SO用户都使用VS).

And*_*ico 11

在已/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.
Run Code Online (Sandbox Code Playgroud)

prefastDDK/WDK附带的工具会产生类似的警告.

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

  • 我相信以前的版本就是这种情况,但是从VS 2013开始[所有版本都有它](http://blogs.msdn.com/b/hkamel/archive/2013/10/24/visual-studio-2013-静态代码分析,深入的 - 什么 - 和 - how.aspx时). (3认同)

Jer*_*fin 6

编译器几乎可以发出任何警告,但在这种情况下,编译器很难给出真正有意义的警告.

特别是,在链接时间之前不会真正选择堆栈大小.编译器在链接器之前运行,因此它基本上不可能知道在运行链接器时可能选择的堆栈大小.因此,如果编译器要发出警告,那么它可以做的最好的事情就是假设某些"合理的"堆栈大小将被选中,并将警告基于违反该规则.

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

sub esp, 123456 ; or sub rsp, 123456 in 64-bit code.
Run Code Online (Sandbox Code Playgroud)

链接器必须找到堆栈指针被操纵的每个位置,并检查所涉及的数字的大小以有意义地发出警告.要做到这一点,它基本上必须弄清楚代码是什么,数据是什么,并反汇编和检查代码(但不是数据,可能会反汇编为无意义的代码).这可能是可能的,但可能有些不平凡,而且肯定超出了连接器通常做或使用的事物的范围.