Calling global function before declaration

On stackoverflow (and some other sources) it was said, that global functions have to be declared before you can use them. But I noticed, that nowadays this code is legal (terminal application):

changeGlobal()
func changeGlobal() {
    x += 1
}
print(x)    // "1"
var x = 10

Even the global variable is defined at the end though the output is 1 instead of 11. (Global variables seem to be "preinitialized" with an "empty" value before actually running the code?) I have looked into the changelog but could not find, when they changed the behavior of Swift, made it possible to call a global function before declaration.

[The docs for TopLevel Code ] - see:Declarations — The Swift Programming Language (Swift 5.7))

say: "The top-level code in a Swift source file consists of zero or more statements, declarations, and expressions. By default, variables, constants, and other named declarations that are declared at the top-level of a source file are accessible to code in every source file that is part of the same module."

If declarations are to be accessible in every source file, the place of declaration for top-level code (which is what you are talking about) wouldn't seem important.
AFAICT it has always been that way.
Here's an example with top-level var declaration after being referenced

func test(){num = 1}

var num:Int

The documentation neither explicitly forbid nor allow the usage of a function before its declaration. (Whatever "before" means when dealing with multiple files...) I would also say, that the place of top-level functions isn't important, at least currently. However the place of top-level variable-declarations seems to be important: That's why the output of my example is "1" instead of "11". But I still do not understand, why claims have arisen, that it is not possible to call a global function before its declaration in Swift. I recently read this assertion in a new book. There must have been a change in the compiler recently?

But I still do not understand, why claims have arisen, that it is not
possible to call a global function before its declaration in Swift.

My experience is that playgrounds (and probably the REPL) and standard compiled code behave differently when it comes to top-level code. Whenever you evaluate a statement about that, make sure you clarify which context the author is testing.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

2 Likes

It is about code written with the command line tool template.

I think this is a bug, here's a reduced example:

// This program compiles and print 0 when run:
print(x) 
let x = 123
// This program compiles and crashes (segmentation fault 11) when run:
print(x) 
let x = [1, 2, 3]

Are you sure that this hasn't always been the case? See for example this old perhaps somewhat related thread:


If it the behavior has changed in Swift 5.2, then it seems like more/different bugs have been introduced, since the example in the end of the following old post now compiles (though @jrose says at the end of the post that it is important to make sure it continues to be rejected):