gpt4 book ai didi

c++ - 如何强制 MSVC 编译器省略大型临时对象的堆栈分配?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:14:17 24 4
gpt4 key购买 nike

这个问题不是 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 有一个 Non trivial Destructor,对 ms.~my_struct() 的显式调用必须在放置 new 之前。供引用:new expression

我建议不要以正常方式使用此技术。它是一种“黑魔法”低级 C++。好的编译器应该使用 memset 进行优化。

顺便说一句,oh_my 全局变量不会在堆栈上分配一个临时变量,因为它在编译时被常量初始化

关于c++ - 如何强制 MSVC 编译器省略大型临时对象的堆栈分配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53725492/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com