【发布时间】:2019-05-12 12:33:37
【问题描述】:
此问题与this one 或其他类似问题不重复。这个问题是关于清除一个结构在它已经被初始化和使用过。
更新
在阅读了您的前几篇 cmets 之后,我想澄清一下我的问题:
- 如何强制 MSVC 编译器忽略大堆栈分配?
我已经更新了标题、文本和下面的代码来澄清这一点。
我最近开始使用/GS、/sdl 和/analyze 编译器选项编译我的项目。 (Microsoft Visual C++ 2015)使用这些选项,编译器可以正确警告有问题的代码结构。但是,我遇到了一些我一直认为是好的 C++ 风格的警告。
请看下面的示例代码:
struct my_struct {
char large_member[64000];
};
void do_something_else(my_struct & ms)
{
// the intent of the next line is to "clear" the ms object
ms = {}; // <-- here the compiler claims the large stack allocation
// ... do some more work with ms
}
my_struct oh_my = {}; // construction, apparently no large stack allocation
int main()
{
// ...
// do something with the oh_my object
//
do_something_else(oh_my);
}
有人告诉我,清除结构的标准 C++ 方法如下:
ms = {};
使用/analyze 选项,编译器会通过以下方式发出警告(示例):
C:\Dev\MDS\Proj\MDSCPV\Vaps_Common_lib\camber_radar.cpp:162:警告:C6262:函数使用堆栈的 '144400' 字节:超过 /analyze:stacksize '16384'.. 此分配用于编译器在第 162 行为“struct BitmapBuffer”生成临时文件。考虑将一些数据移动到堆中。
我认为会发生以下情况:
- 在堆栈上构造了一个临时对象
- 临时对象被复制到对象变量中
我希望看到类似默认初始化的情况。在我看来,编译器应该能够优化堆栈分配。但显然(根据警告)编译器没有这样做。 我的问题是:如何强制编译器忽略堆栈分配? 我现在已经开始用以下代码替换这些地方:
std::memset(&ms, 0, sizeof(ms));
【问题讨论】:
-
在发布模式(开启优化)下构建时是否也会收到警告?
-
是的,我在发布模式下得到了它。我正在使用
/GS /analyze选项进行发布构建。 (/GS和/sdl在某种程度上相互排斥) -
对我来说似乎很好。您在堆栈上分配了两个至少
64000字节的结构,鉴于阈值是 16384 字节,编译器有权抱怨。 -
@user10605163,“不能省略”是什么意思? GCC 和 Clang 为该行生成一个
memset调用:godbolt.org/z/G6CQO_ -
@Evg 是的,我不知道我在想什么。
标签: c++ visual-c++ initialization stack-allocation