When does a deferred func actually runs?
Before reading this, read the comment of one of my readers here. I might be wrong or right about this. So, please take this with a grain of salt.
It’s been said that a deferred func runs after its surrounding func returns. But, I’m not exactly sure “after” is the right word.
So, let’s see how it works behind the scenes
If we look at the internals of the return statement in the compiler (in the ssa builder of the Go compiler), we can see that the compiler puts “defer calls” “just before the return” and then does “return”. Please check out the underlined words in this paragraph to see what I mean.
The runtime reserves a stack space in the surrounding func’s stack for defers — for example, this also enables using the named result params to be changed by the deferred func. So, they share the same stack.
In the exit func you can even see that its behavior has been commented as “before” — not “after”. Exit func is used in ssa builder of Go compiler backend to generate a code for a func’s return.
“exit processes any code that needs to be generated just before returning” — here.
So, basically, defers run like this:
return /* defers run here */ ...
But, technically run like this:
/* deferred funcs run here */
You may say that it can’t be. Because, in this example of my reader, he sees that the value of “i” variable is 0, not 1. But, behind the scenes, the compiler actually puts the variable into a temporary variable to make you see as if it was 0, actually, it becomes 1.
👉 Check out the old-ssa code (~the interim compiled code) that I generated for this example, here.
So, how it works?
Not like this:
// not here! - not after.
Or not like this:
// not here - not after
But, as you see within the example code, it “acts as it runs defers after the func returns”.
In this article, I’ve tried to write about the internal behavior, not about according to the Go Spec.
Check out the Go Defers main article:
Alright, that’s all for now. Thank you for reading so far.
Let’s stay in touch:
- 📩 Join my newsletter
- 🐦 Follow me on twitter
- 📦 Get my Go repository for free tutorials, examples, and exercises
- 📺 Learn Go with my Go Bootcamp Course
- ❤️ Do you want to help? Please clap and share the article. Let other people also learn from this article.