[swift-evolution] Should Swift apply "statement scope" for ARC
Xiaodi Wu
xiaodi.wu at gmail.com
Wed Sep 21 17:14:02 CDT 2016
I haven't used it myself, but is this the use case addressed by
`withExtendedLifetime(_:_:)`?
On Wed, Sep 21, 2016 at 16:54 John Holdsworth via swift-evolution <
swift-evolution at swift.org> wrote:
> Hi,
>
> For complex statements in C++ any temporary instances created in the course
> of an expression have their lifetime extended to the completion of the
> current
> statement after which they are all deallocated en masse. This makes certain
> types of language usage possible and easier to reason with.
>
> I’m bringing this up as I had a problem with some code crashing only when
> compiled with release configuration and the problem could have been avoided
> if Swift deferred deallocation to the end of a statement. While Swift’s
> ARC policy
> is consistent in itself this seems to be a particular problem interfacing
> between
> language/reference counting systems. My problem code was a Java-Swift
> Bridge.
>
> A contrived example:
>
> import Foundation
>
> protocol Storage {
> var fp: UnsafeMutablePointer<FILE> { get }
> }
>
> class FileStorage: Storage {
>
> let fp: UnsafeMutablePointer<FILE>
>
> init?(path: String, mode: String = "w") {
> print("Opening")
> let fp = fopen(path, mode)
> if fp == nil {
> return nil
> }
> self.fp = fp!
> }
>
> deinit {
> print("Closing")
> fclose(fp)
> }
> }
>
> func save(string: String, to: Storage?) {
> if let data = string.data(using: String.Encoding.utf8) {
> print("Saving1")
> if let fp = to?.fp {
> print("Saving2")
> data.withUnsafeBytes {
> _ = fwrite($0, 1, data.count, fp)
> }
> print("Saving3")
> }
> }
> }
>
> save(string: "Hello World\n", to: FileStorage(path: "/tmp/a.txt"))
>
>
> In debug configuration is prints:
> *Opening*
> *Saving1*
> *Saving2*
> *Saving3*
> *Closing*
>
> Whereas in release configuration it prints:
> *Opening*
> *Saving1*
> *Closing <!!!*
> *Saving2*
> *Saving3*
>
> The optimiser is vigorously deallocating objects when they are no longer
> referenced regardless
> of whether an variable referencing it is still in scope (In fairness this
> particular problem only occurs
> for Optional augments of Protocols) but this behaviour seems to be
> implicit in the current language
> spec. The alternative is to retain arguments themselves as I believe they
> are in Objective-C ARC.
>
> This would have been avoided if the temporary FileStorage instance has
> been considered to have
> a lifetime up to the end of the statement calling function save() and
> hence the duration of the call.
> This needed increase ARC overhead in any way. Just alter the timing of it
> to be more conservative.
>
> John
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160921/8d09f0f8/attachment.html>
More information about the swift-evolution
mailing list