Do you need help on a specific subject? Use the contact form (Request a blog entry) on the right hand side.

2016-12-29

The defer statement | Swift gotcha

I love the defer statement. Use it all the time...

(Note: The defer statement allows you to execute a piece of code just before the scope the statement is in closes)

However today I ran into an inexplicable problem where a file read operation would always fail. And as so often I simply could not see the error until I stepped through. The error turned out to be quite simple: a defer statement at the wrong place.

This was the offending code:

let path = "/Users/Home/Me/Desktop/file.txt"

let file = fopen(path, "r")

if file == nil {
    print("Error opening file at \(path)")
} else {
    defer { fclose(file) }
}

let result = read(from: file)

...

Do you spot the error?

Right! the defer statement is executed immediately because the end-of-scope is the "}" closing the "else" part.

So the file was already closed when the read operation was called.
The solution is obvious:

let path = "/Users/Home/Me/Desktop/file.txt"

let file = fopen(path"r")

if file == nil {
    print("Error opening file at \(path)")
}
defer { fclose(file) }

let result = read(from: file)

...

The rule of thumb is clear: Always place the defer stement at the same "level" or "indent" as the variable it refers to. Which -to be clear- simply means "the same scope".

Happy coding...

Did this help?, then please help out a small independent.
If you decide that you want to make a small donation, you can do so by clicking this
link: a cup of coffee ($2) or use the popup on the right hand side for different amounts.
Payments will be processed by PayPal, receiver will be sales at balancingrock dot nl
Bitcoins will be gladly accepted at: 1GacSREBxPy1yskLMc9de2nofNv2SNdwqH

We don't get the world we wish for... we get the world we pay for.

No comments:

Post a Comment