Implicitly initialised global variables

Swift kind of allows the use of global variables before explicit initialisation. For example, the following code runs fine and prints out a 0

func foo() {
  print(x)
}

let x: Int
foo() // 0

However moving the declaration of x above func foo produces an error. "variable 'x' used by function definition before being initialized"

let x: Int

func foo() {
  print(x)
}

foo() // 0

I would basically just like to clarify whether this is a bug or intended behaviour?


SIDE-NOTE:

The error that is produced in the latter example becomes unfortunate since one cannot declare a variable before a func declaration, but initialise it before a func call. Where the following is invalid:

var x: Int

func foo() {
  print(x)
}

x = 5
foo()

That's pretty interesting, I've never known this was possible, because I generally try to avoid using global variables (for reasons I'm sure most people are familiar with.) I remember running into (what I thought was) some strange behavior, that stemmed from the fact that globals are actually calculated lazily. Sadly I don't remember the exact case.

FWIW, here's looking at the first example in x86: Compiler Explorer

1 Like

This looks like a hole in the definitive-initialization logic rather than intended behavior.

3 Likes

These are all bugs. You should neither be allowed to invoke a function before the variables it captures are initialized, nor should you be prevented from invoking a function after the variables it captures have been initialized. Chances are these examples would give the behavior you expect if you put them in a function body; we have some known issues enforcing these rules with top-level code.

6 Likes

Yeah, after thinking about this more, and changing the type of the variable to something non-trivial, it's pretty obvious this is a bug, and can lead to some non-sensical things.