<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 10, 2015, at 8:46 AM, Jason Pollack via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">I was experimenting in Swift with RAII, a technique I find very useful from C++.&nbsp; In general it works well, but there is something I found unexpected.<div class=""><br class=""></div><div class="">Consider this class:</div><div class=""><br class=""></div><div class=""><p class=""><span class="">class</span><span class=""> RAII {<br class=""></span><span class="">&nbsp; &nbsp;&nbsp;</span><span class="">init</span><span class="">() {<br class=""></span><span class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="">print</span><span class="">(</span><span class="">"some resource acquired"</span><span class="">)<br class=""></span>&nbsp; &nbsp;&nbsp;}<br class=""><span class="">&nbsp; &nbsp;&nbsp;</span><span class="">deinit</span><span class=""> {<br class=""></span><span class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="">print</span><span class="">(</span><span class="">"some resource released"</span><span class="">)<br class=""></span>&nbsp; &nbsp;&nbsp;}<br class="">}</p><p class="">And this sample code:<br class=""></p><p class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="">let</span><span class=""> b = </span><span class="">true<br class=""></span><span class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="">if</span><span class=""> (b)<br class=""></span>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;{<br class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="">print</span><span class="">(</span><span class="">"Entered scope"</span><span class="">)<br class=""></span><span class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="">let</span><span class=""> raii = </span><span class="">RAII</span><span class="">()<br class=""></span><span class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="">print</span><span class="">(</span><span class="">"Going out of scope"</span><span class="">)<br class=""></span>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;}<br class=""><span class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span class="">print</span><span class="">(</span><span class="">"Left scope"</span><span class="">)</span></p><p class=""><span class="">As expected, I see the output:</span></p></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""><div class=""><p class=""><span class="">Entered scope<br class=""></span>some resource acquired<br class="">Going out of scope<br class="">some resource released<br class="">Left scope</p></div></blockquote><div class=""><p class=""><span class="">However, the compiler gives me a warning on the 'let raii = ' line: &nbsp;"Initialization of immutable value 'raii' was never used; consider replacing with assignment to '_' or removing it"<br class=""><br class="">If I change that line to:</span></p></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""><div class=""><p class=""><span class="">let _ = RAII()</span></p></div></blockquote>the warning goes away, but I get the unexpected output:<br class=""><br class=""><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""><div class=""><span class="">Entered scope</span></div><div class="">some resource acquired</div><div class="">some resource released</div><div class="">Going out of scope</div><div class="">Left scope<br class=""></div><div class=""><br class=""></div></blockquote>It appears the object instance is being destroyed immediately after being created, because the compiler correctly sees that nobody needs it.<div class=""><br class=""></div><div class="">Therefore, I propose that such instances stay referenced until the end of the scope they are declared in.&nbsp;</div></div></div></blockquote><div><br class=""></div><div>ARC does not normally guarantee scoped lifetimes; the optimizer will shorten lifetimes so that objects get released after their last use, not when their variable goes out of scope. If you don't use the result of a computation at all, it will likely be immediately released. You can use `withExtendedLifetime` to set a minimum bound for the lifetime of a reference:</div><div><br class=""></div><div>withExtendedLifetime(RAII()) {</div><div>&nbsp; print("Going out of scope")</div><div>}</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">(As an aside, I would like to see a deinit on a struct to support this technique as well.)</div></div></div></blockquote><br class=""></div><div>If structs support destructors, then they potentially also need to support copy constructors and all the other complexity of C++ to describe what happens when they get copied. Resources really do have referential identity in practice; classes are the appropriate way to model them.</div><div><br class=""></div><div>-Joe</div></body></html>