I haven&#39;t used it myself, but is this the use case addressed by `withExtendedLifetime(_:_:)`?<br><br><div class="gmail_quote"><div dir="ltr">On Wed, Sep 21, 2016 at 16:54 John Holdsworth via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">Hi,<div><br></div><div>For complex statements in C++ any temporary instances created in the course</div><div>of an expression have their lifetime extended to the completion of the current</div><div>statement after which they are all deallocated en masse. This makes certain</div><div>types of language usage possible and easier to reason with.</div><div><br></div><div>I’m bringing this up as I had a problem with some code crashing only when</div><div>compiled with release configuration and the problem could have been avoided</div><div>if Swift deferred deallocation to the end of a statement. While Swift’s ARC policy</div><div>is consistent in itself this seems to be a particular problem interfacing between</div><div>language/reference counting systems. My problem code was a Java-Swift Bridge.</div><div><br></div><div>A contrived example:</div><div><br></div><div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">import</span><span> Foundation</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span></span><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">protocol</span><span> Storage {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)"><span style="color:#000000">    </span><span style="color:#bb2ca2">var</span><span style="color:#000000"> fp: </span><span>UnsafeMutablePointer</span><span style="color:#000000">&lt;</span><span>FILE</span><span style="color:#000000">&gt; { </span><span style="color:#bb2ca2">get</span><span style="color:#000000"> }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>}</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span></span><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">class</span><span> FileStorage: </span><span style="color:#4f8187">Storage</span><span> {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span></span><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)"><span style="color:#000000">    </span><span style="color:#bb2ca2">let</span><span style="color:#000000"> fp: </span><span>UnsafeMutablePointer</span><span style="color:#000000">&lt;</span><span>FILE</span><span style="color:#000000">&gt;</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span></span><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>    </span><span style="color:#bb2ca2">init</span><span>?(path: </span><span style="color:#703daa">String</span><span>, mode: </span><span style="color:#703daa">String</span><span> = </span><span style="color:#d12f1b">&quot;w&quot;</span><span>) {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>        </span><span style="color:#3d1d81">print</span><span>(</span><span style="color:#d12f1b">&quot;Opening&quot;</span><span>)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>        </span><span style="color:#bb2ca2">let</span><span> fp = </span><span style="color:#3d1d81">fopen</span><span>(path, mode)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>        </span><span style="color:#bb2ca2">if</span><span> fp == </span><span style="color:#bb2ca2">nil</span><span> {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>            </span><span style="color:#bb2ca2">return</span><span> </span><span style="color:#bb2ca2">nil</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>        }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>        </span><span style="color:#bb2ca2">self</span><span>.</span><span style="color:#4f8187">fp</span><span> = fp!</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>    }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span></span><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>    </span><span style="color:#bb2ca2">deinit</span><span> {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>        </span><span style="color:#3d1d81">print</span><span>(</span><span style="color:#d12f1b">&quot;Closing&quot;</span><span>)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>        </span><span style="color:#3d1d81">fclose</span><span>(</span><span style="color:#4f8187">fp</span><span>)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>    }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>}</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span></span><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">func</span><span> save(string: </span><span style="color:#703daa">String</span><span>, to: </span><span style="color:#4f8187">Storage</span><span>?) {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>    </span><span style="color:#bb2ca2">if</span><span> </span><span style="color:#bb2ca2">let</span><span> data = string.</span><span style="color:#3d1d81">data</span><span>(using: </span><span style="color:#703daa">String</span><span>.</span><span style="color:#703daa">Encoding</span><span>.</span><span style="color:#703daa">utf8</span><span>) {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>        </span><span style="color:#3d1d81">print</span><span>(</span><span style="color:#d12f1b">&quot;Saving1&quot;</span><span>)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>        </span><span style="color:#bb2ca2">if</span><span> </span><span style="color:#bb2ca2">let</span><span> fp = to?.</span><span style="color:#4f8187">fp</span><span> {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>            </span><span style="color:#3d1d81">print</span><span>(</span><span style="color:#d12f1b">&quot;Saving2&quot;</span><span>)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>            data.</span><span style="color:#3d1d81">withUnsafeBytes</span><span> {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>                </span><span style="color:#bb2ca2">_</span><span> = </span><span style="color:#3d1d81">fwrite</span><span>($0, </span><span style="color:#272ad8">1</span><span>, data.</span><span style="color:#703daa">count</span><span>, fp)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>            }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>            </span><span style="color:#3d1d81">print</span><span>(</span><span style="color:#d12f1b">&quot;Saving3&quot;</span><span>)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>        }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>    }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>}</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span></span><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)"><span style="color:#31595d">save</span><span style="color:#000000">(string: </span><span>&quot;Hello World\n&quot;</span><span style="color:#000000">, to: </span><span style="color:#4f8187">FileStorage</span><span style="color:#000000">(path: </span><span>&quot;/tmp/a.txt&quot;</span><span style="color:#000000">))</span></div></div><div><span style="color:#000000"><br></span></div><div><br><div><div>In debug configuration is prints:</div></div></div><div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span><b>Opening</b></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span><b>Saving1</b></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span><b>Saving2</b></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span><b>Saving3</b></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span><b>Closing</b></span></div></div><div><br></div><div><div>Whereas in release configuration it prints:</div></div><div><b style="font-family:Menlo;font-size:11px">Opening</b></div><div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span><b>Saving1</b></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span><b>Closing &lt;!!!</b></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span><b>Saving2</b></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span><b>Saving3</b></span></div></div><div><span><b><br></b></span></div><div><div>The optimiser is vigorously deallocating objects when they are no longer referenced regardless</div><div>of whether an variable referencing it is still in scope (In fairness this particular problem only occurs</div><div>for Optional augments of Protocols) but this behaviour seems to be implicit in the current language</div><div>spec. The alternative is to retain arguments themselves as I believe they are in Objective-C ARC.</div></div><div><br></div><div>This would have been avoided if the temporary FileStorage instance has been considered to have</div><div>a lifetime up to the end of the statement calling function save() and hence the duration of the call.</div><div>This needed increase ARC overhead in any way. Just alter the timing of it to be more conservative.</div><div><br></div><div>John</div><div><br></div></div>_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div>