# Targeting a specific scope with defer

**URL:** <https://forums.swift.org/t/targeting-a-specific-scope-with-defer/69942>\
**Category:** Using Swift\
**Tags:** defer-statement\
**Created:** [February 9, 2024, 9:25pm UTC](https://forums.swift.org/t/targeting-a-specific-scope-with-defer/69942 "2024-02-09T21:25:45Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![wadetregaskis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wadetregaskis/32/8494_2.png) [@wadetregaskis](https://forums.swift.org/u/wadetregaskis)\
**Post date:** [February 9, 2024, 9:25pm UTC](https://forums.swift.org/t/targeting-a-specific-scope-with-defer/69942/1 "2024-02-09T21:25:45Z")

</div>

Is there a way to specify _which_ scope a deferred block should run at the end of, rather than just the current scope?

e.g. I might want to write:

```swift
var data: UnsafeMutablePointer<UInt8>

if someCondition {
    data = someNonOwnedResult
} else {
    data = someOwnedResult
    defer { data.deallocate() } // 🚨 Runs too early.

    try … // More work here contingent on !someCondition.
}

try doSomething(with: data)

// *Now* I want to deallocate `data` (if necessary).

```

I want that defer to run at the end of the outer scope (typically the function's full scope, but not always), but as far as I can tell there's no elegant way to do that today?

Typically I end up with something like:

```swift
var data: UnsafeMutablePointer<UInt8>
var deallocateData = false

let condition = someCondition

if condition {
    data = someNonOwnedResult
} else {
    data = someOwnedResult
    deallocateData = true
}

defer {
    if deallocateData {
        data.deallocate()
    }
}

if !condition {
    try … // Finish doing all the other !someCondition stuff.
}

try doSomething(with: data)

```

Even in this contrivedly-trivial case that's pretty unappealing, let-alone in real-world code with multiple levels of indentation (when `data` is populated and its deallocation requirement determined) and with much more stuff in-between the key points.

I feel like it'd be quite helpful if defers could be targeted to labels, including an implicit label for the enclosing function, e.g.:

```swift
var data: UnsafeMutablePointer<UInt8>

if someCondition {
    data = someNonOwnedResult
} else {
    data = someOwnedResult
    defer to function exit { data.deallocate() }

    try … // More work here contingent on !someCondition.
}

try doSomething(with: data)

```

I know there's other workarounds like making a wrapper type for the object & the flag of whether it should be deleted, and handling that in object deinit, but that's conceptually heavy-weight for such a simple task. (made better, semantically, with non-copyable types so that it can be a struct, but even so)

---

<div class="post-metadata">

**Author:** ![za\_creature](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/za_creature/32/32730_2.png) [@za\_creature](https://forums.swift.org/u/za_creature)\
**Post date:** [February 9, 2024, 9:42pm UTC](https://forums.swift.org/t/targeting-a-specific-scope-with-defer/69942/2 "2024-02-09T21:42:44Z")

</div>

> [@wadetregaskis](#):
>
> ```swift
> if someCondition {
> data = someNonOwnedResult
> } else {
> data = someOwnedResult
> defer { data.deallocate() } // 🚨 Runs too early.
> 
> try … // More work here contingent on !someCondition.
> }
> 
> try doSomething(with: data)
> 
> ```

I guess just use a function:

```swift
if someCondition {
    try doSomething(with: data)
} else {
    defer { someOwnedResult.deallocate() }
    try doSomething(with: someOwnedResult)
}

```

A bit clumsy, but more explicit and likely easier to read (to me, at least).

Whenever I find myself wishing for a `break n / continue n` statement, I tend to refactor it into a function with early returns. Both situations are more or less `goto`s and, as you mention...

> [@wadetregaskis](#):
>
> in real-world code with multiple levels of indentation

... are quite difficult to follow

Alternatively, you could save one level of indentation with:

```swift
guard !someCondition else { return try doSomething(with: data) }

defer { deallocate() }
try … // More work here contingent on !someCondition.
try doSomething(with: data)
```

---

<div class="post-metadata">

**Author:** ![jpmhouston](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jpmhouston/32/4045_2.png) [@jpmhouston](https://forums.swift.org/u/jpmhouston)\
**Post date:** [April 18, 2024, 2:20am UTC](https://forums.swift.org/t/targeting-a-specific-scope-with-defer/69942/3 "2024-04-18T02:20:05Z")

</div>

Late to this discussion, but I've just come across it in a search after having to do a clumsy workaround for Swift's limited defer. Every option makes my code suck.

This should be another use for labelled control flow statements, they get so little love already. New alternate forms of `defer` should be:

```swift
defer outer {
    // runs not when the closest scope ends but rather the one labelled with "outer"
}

```

and this special case that uses the `func` keyword in place of a label:

```swift
defer func {
    // runs not when the closest scope ends but rather the enclosing function
}

```

Is there anyone interested and able to help me pitch this to Swift Evolution?
