<story><title>Is Rust stack-efficient yet?</title><url>https://arewestackefficientyet.com/</url></story><parent_chain><item><author>klodolph</author><text>There’s a broader problem here, which also applies to the C++ ecosystem, which is that debug builds are far less usable than they should be. C++ compilers in common debug configurations will emit a function call for std::move(), which is not in any way useful for typical debugging tasks and can make the program significantly slower.&lt;p&gt;I don’t want to rely on compiler optimizations to make my code work. Or alternatively, find a way to deliver those optimizations in debug builds.&lt;p&gt;The idea of using a Vec would be nice—if only the boxed item were an array! It’s a struct, you see…</text></item><item><author>sitkack</author><text>Box::new allocating on the stack and moving is only true in debug builds, in release builds it directly allocates on the heap. Not apologizing, just explaining. It is being fixed, the interim solution is to use a Vec.</text></item><item><author>klodolph</author><text>This affects the way you write code, too.&lt;p&gt;I was writing something in Rust and I wanted to create a new boxed object.&lt;p&gt;&lt;pre&gt;&lt;code&gt;  Box::new(...)
&lt;/code&gt;&lt;/pre&gt;
Boom! Program crashes. The object I’m putting in the heap is too large for the stack. Rustc does this by instantiating the object on the stack, and then copying it to the box. I don’t really want to fuss with nightly or stuff like Box::new_uninit just to deal with this. C++ has both regular `new` and placement `new`, both of which put objects in memory which is already allocated. I had assumed that the Rust compiler could optimize out a move, since that’s such a prominent feature in C++ compilers.</text></item></parent_chain><comment><author>codeflo</author><text>Having been bitten by that exact problem in C++, I think the original sin is to treat stuff like copy elision as a mere optimization, instead of a semantic guarantee.</text></comment>
<story><title>Is Rust stack-efficient yet?</title><url>https://arewestackefficientyet.com/</url></story><parent_chain><item><author>klodolph</author><text>There’s a broader problem here, which also applies to the C++ ecosystem, which is that debug builds are far less usable than they should be. C++ compilers in common debug configurations will emit a function call for std::move(), which is not in any way useful for typical debugging tasks and can make the program significantly slower.&lt;p&gt;I don’t want to rely on compiler optimizations to make my code work. Or alternatively, find a way to deliver those optimizations in debug builds.&lt;p&gt;The idea of using a Vec would be nice—if only the boxed item were an array! It’s a struct, you see…</text></item><item><author>sitkack</author><text>Box::new allocating on the stack and moving is only true in debug builds, in release builds it directly allocates on the heap. Not apologizing, just explaining. It is being fixed, the interim solution is to use a Vec.</text></item><item><author>klodolph</author><text>This affects the way you write code, too.&lt;p&gt;I was writing something in Rust and I wanted to create a new boxed object.&lt;p&gt;&lt;pre&gt;&lt;code&gt;  Box::new(...)
&lt;/code&gt;&lt;/pre&gt;
Boom! Program crashes. The object I’m putting in the heap is too large for the stack. Rustc does this by instantiating the object on the stack, and then copying it to the box. I don’t really want to fuss with nightly or stuff like Box::new_uninit just to deal with this. C++ has both regular `new` and placement `new`, both of which put objects in memory which is already allocated. I had assumed that the Rust compiler could optimize out a move, since that’s such a prominent feature in C++ compilers.</text></item></parent_chain><comment><author>tialaramex</author><text>I &lt;i&gt;guess&lt;/i&gt; what they mean is that the Vec would allocate heap space, and you could steal the allocation for your object to make the Box? You&amp;#x27;d need to create this MyType manually and then tell Box what you made unsafely with like Box::from_raw()&lt;p&gt;It feels like a better way to do that directly with Box is Box::&amp;lt;MyType&amp;gt;::new_zeroed() which will make you a Box&amp;lt;MaybeUninit&amp;lt;MyType&amp;gt;&amp;gt; full of zero bytes. If MyType is definitely valid when made entirely of zero bytes and you&amp;#x27;re sure of that, you can unsafely assume_init() to have the MaybeUninit resolve to an actual MyType.&lt;p&gt;[[ If you lied, now everything is on fire, I did warn you that you need to be sure and it is an unsafe function ]]&lt;p&gt;If MyType is very much not valid if consisting entirely of zero bytes well, new_uninit() gives you memory in unspecified (must not be read) state, you can properly initialise it and then assume_init() as before - but all the extra work kinda sucks, and in either case clearly it would be nicer to just write what you meant and have it work.</text></comment>