此问题与
this one或其他类似问题不重复.这个问题是关于在初始化和使用它之后清除结构.
更新
在阅读了您的前几条评论之后,我想澄清一下我的问题:
>如何强制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: warning: C6262: Function uses ‘144400’ bytes of stack: exceeds /analyze:stacksize ‘16384’.. This allocation was for a compiler-generated temporary for ‘struct BitmapBuffer’ at line 162. Consider moving some data to heap.
我认为会发生以下情况:
>在堆栈上构造临时对象
>临时对象被复制到对象变量
我希望看到像那里发生的默认初始化.在我看来,编译器应该能够优化堆栈分配.但显然(根据警告)编译器不会这样做.
我的问题是:如何强制编译器忽略堆栈分配?
我现在开始用以下代码替换这些地方:
std::memset(&ms, 0, sizeof(ms));
最佳答案 由于my_struct很容易复制,编译器应该能够放置一个memset调用而不是创建一个临时调用,然后分配它,但它不是必需的.
Placement new表达式将解决您的问题:它使用提供的构造函数在预分配的地址构造对象.例如,new(& ms)my_struct {}给出与ms = {}相同的语义.如果my_struct有一个非平凡的析构函数,则显式调用ms.~my_struct()必须在placement new之前.供参考:new expression
我建议不要以正常的方式使用这种技术.它是一种’黑魔法’低级别C级.好的编译器应该使用memset进行优化.
顺便说一下,oh_my全局变量不会在堆栈上分配临时值,因为它是在编译时初始化的常量.