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