c – 如何强制MSVC编译器忽略大型临时对象的堆栈分配?
此问题与
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选项,编译器会以下列方式警告此情况(示例):
我认为会发生以下情况: >在堆栈上构造临时对象 我希望看到像那里发生的默认初始化.在我看来,编译器应该能够优化堆栈分配.但显然(根据警告)编译器不会这样做. std::memset(&ms,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全局变量不会在堆栈上分配临时值,因为它是在编译时初始化的常量. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |