0

In the first place, I looked for a way to simplify coding by providing default argument values for protocol functions. I took the solution here and then found some fatal subsequence it may bring:

protocol Foo {
    func foo(_ a: Int)
}

extension Foo {
    func foo(_ a: Int = 4) {
        foo(a)
    }
}

struct FooImpl: Foo {
    // empty implementation
}

FooImpl().foo() // will go recursively forever and finally reach the stack limit

I also found that this code would fail to compile in IBM Swift Sandbox thus supposing xcode compiler might be to blame.

Community
  • 1
  • 1
Nandin Borjigin
  • 2,094
  • 1
  • 16
  • 37

2 Answers2

4

This looks to be valid Swift code that the compiler should accept and execute. That it contains a fatal infinite recursion is a logic error on the part of the programmer.

I don't see anything in the IBM Swift Sandbox to indicate that it handles the code any better, or differently, than Xcode.

Scott Thompson
  • 22,629
  • 4
  • 32
  • 34
  • IBM Sandbox says "The Swift compiler reported a segmentation fault or similar error." and if I add an implementation to the `FooImpl` or make the extension non-recursive, the sandbox would accept the code. – Nandin Borjigin May 13 '17 at 08:29
  • The sandbox only says that when you ask it to run the code. At which time you try to perform an infinite recursion which causes a crash and leads to the error. If you add an implementation to `FooImpl` then you are no longer executing the default implementation that makes the infinitely recursive call that is causing the crash. – Scott Thompson May 13 '17 at 08:31
0

You omitted a very important part of the implementation. If you do this you have to implement foo in FooImpl. If you do not implement it your code is basically equivalent to

protocol Foo {
}

extension Foo {
    func foo(_ a: Int = 4) {
        foo(a)
    }
}

struct FooImpl: Foo {
}

FooImpl().foo()

which obviously creates an infinite loop. If you correctly implement foo you will see the expected behaviour:

protocol Foo {
    func foo(_ a: Int)
}

extension Foo {
    func foo(_ a: Int = 4) {
        foo(a)
    }
}

struct FooImpl: Foo {
    func foo(_ a: Int) {
        print(a)
    }
}

FooImpl().foo()

Both are perfectly valid swift snippets, the only difference is that one actually works, the other will crash. But that is nothing the compiler is supposed to worry about.

luk2302
  • 55,258
  • 23
  • 97
  • 137