Hello,

It looks like you want compiler guarantees that an object will be "deinited" at 
the end of a syntactic block:

        func f() {
                let a = Object()
                ...
                // <- guarantee that a.deinit is called here
        }

Currently, Swift does not grant such guarantee. If the object gets retained 
somewhere, its deallocation is postponed:
        
        var storage: [Object] = []
        func f() {
                let a = Object()
                storage.append(a)
                // <- a.deinit is not called here
        }

With your proposal, the code above would not compile.

The current Swift way to guarantee "cleanup" tasks is the `defer` statement:

        func f() {
                let a = Object()
                defer { a.cleanup() }
                ...
        }

But this has several defects: object is not fully responsible of its state, and 
one can get "zombie" values that stay around:

        var storage: [Object] = []
        func f() {
                let a = Object()
                defer { a.cleanup() } // <- can be forgotten
                storage.append(a) // <- storage will contain "zombie" object
        }

So I understand how it looks like Swift does not currently support what C++ 
programmers are used to when they mix RAII with guaranteed stack allocation. 
Note, though, that in C++ guaranteed stack allocation comes for the declaration 
of a value, not from its type.

Is it the correct context of your pitch? Given the immense C++ experience of 
Swift designers, this is surely something they know pretty well. I don't know 
why they did not bring this to Swift. This question itself is an interesting 
topic!

Gwendal


> Le 27 oct. 2017 à 15:27, Mike Kluev via swift-evolution 
> <[email protected]> a écrit :
> 
> if it wasn't already discussed here is the preliminary proposal, if it was 
> then my +1 to the feature.
> 
> i propose we have an explicit apparatus to denote classes having stack 
> storage.
> 
> stack class StackObject { // guaranteed to be on stack
> }
> 
> class NonStackObject { // is not guaranteed to be on stack, can be on heap as 
> well
> }
> 
> this is for performance reasons. sometimes what we need is “structs with 
> deinit” and as this is not going to happen the next best thing could be 
> “lightweight” classes. this shall be self obvious, here are few examples:
> 
> stack class StackObject {
>     var variable = 0
> 
>     func foo() {
>         print(“i am ok to live on stack”)
>     }
> }
> 
> stack class BadObject {
>     var variable = 0
> 
>     func foo() {
>         DispatchQueue.main.async {  // error: can’t be a stack class
>             self.variable = 1
>         }
>     }
> }
> 
> class NonStackObject {
>     …
> }
> 
> foo() {
>     let stackObject = StackObject()
> 
>     DispatchQueue.main.async {
>         stackObject.foo()  // error: can’t use a stack object in this context
>     }
> }
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to