Global variables in Swift are not variables

Global variables in Swift are not variables

The title sounds pretty strange, but I will explain what it means.While playing with Swift I’ve faced weird behaviour, a feature in fact, which isn’t covered in documentation (at least I didn’t find any references!).UPD: shame on me, how could I miss this?Global constants and variables are always computed lazily, in a similar manner to Lazy Stored Properties. Unlike lazy stored properties, global constants and variables do not need to be marked with the @lazy;drGlobal variables are functions and their actual values instantiate on demand

The problem

I wanted to perform some function from different translation unit without explicit calling, and decided to try old C++ trick with global variable:After compiling and running this program you’ll see “hello, world!” in the output, so I’ve tried the same trick with swift:But had no luck… This program does nothing in swift.


At the first glance, it looks like compiler optimisation, but what if we call this variable from debugger?It works. Weird. But it works!Ok, so let’s access to this variable from main.swift:It works as well, so variable instantiates at the first call. But how it works and why? To understand how it works we definitely should dive deeper into the executable. Usually I’m using LLVM IR for such purposes, but this time I decided to use Hopper, ’cause it has a very useful feature: ‘Show pseudocode’After opening the executable via Hopper you may see that app also has function main as an entry point, this function calls _top_level_code, which consists of main.swift. Let’s look at pseudocode of _top_level_code:and get rid of ‘garbage’Instead of direct access to variable, it calls respective function; let’s look at it:it calls another function swift_once and returns actual variable globalVar. Ok, let’s go deeper, currently we’re interested in the second parameter: _globalinit_func0, it’s also function:Caught it! Finally, we’ve found function which does exactly what we want:


Any global variable in Swift is being replaced with respective function call that initializes this variable on demandLet’s wrap up our small research!This codetranslates into this one:So, now this behaviour is clear, but question ‘why such a decision was made?’ is still open.Happy hacking, guys, and be careful!