-3

Edit: finished, duplicate of Why doesn't this obvious infinite recursion give a compiler warning? I believed that given the many clever warnings Swift has and also the designated initialiser system that it was reasonable to expect a warning, but this is wrong, as explained in the above.

I found this interesting example by playing around with protocol extensions, then realised it screws up structs as well.

struct WhatThe {
let a = 1
init(value: Int) {
    self.init()
}

init() {
    self.init(0)
}
}

print(WhatThe().a) //nothing is printed and the CPU goes nuts.

This is a bug isn't it? I understand this is an infinite loop, I'm just really surprised Apple allowed this. This code has no warnings and builds fine, Playground even runs it. I feel like this kind of thing was an obvious issue in the language to get rid of. It's fine in classes right?- because these are both convenience initialisers?

Community
  • 1
  • 1
Richard Birkett
  • 771
  • 9
  • 20
  • This is not a bug, but the special case of infinite loops that is _infinite recursion_, which is quite a common _developer error_, not in any way specifically related to Swift initializers. An even more simple initializer example is e.g. `struct Foo { init() { self.init() } }`, invoking (as for your example above) infinite recursion for when a `Foo` instance is initialized; readily comparable with the more well-known infinite recursion example of a recursive function just calling itself, say `func foo() { foo() }`, invoking infinite recursion when called; `foo()`. – dfrib Apr 22 '16 at 22:47
  • 1
    Since the root of this question is not really Swift-language-specific, I suggest it be closed as duplicate of e.g. [Infinite recursion in C](http://stackoverflow.com/questions/18227093/infinite-recursion-in-c) or e.g. [Why doesn't this obvious infinite recursion give a compiler warning?](http://stackoverflow.com/questions/8762234/why-doesnt-this-obvious-infinite-recursion-give-a-compiler-warning) (this latter one however closed, still contains a good answer w.r.t. compiler warnings an why these cannot catch infinite recursion). – dfrib Apr 22 '16 at 22:52
  • Thank you both, that's solved it. I have voted to close it as a duplicate of http://stackoverflow.com/questions/8762234/why-doesnt-this-obvious-infinite-recursion-give-a-compiler-warning although the former http://stackoverflow.com/questions/18227093/infinite-recursion-in-c isn't really the same question in my mind. – Richard Birkett Apr 23 '16 at 02:37
  • See my book, where I comment on this very issue: http://www.apeth.com/swiftBook/ch04.html#_delegating_initializers Note the last paragraph of that section, starting with the words "Be careful not to delegate recursively". – matt Apr 23 '16 at 03:01

1 Answers1

2

This is just a case of an infinite loop, your init() function calls init(value:), which in turn calls init() again, and so on, so it never ends. Well, it will end when the stack overflows and will crash.

EmilioPelaez
  • 18,758
  • 6
  • 46
  • 50
  • Sorry I should have been clearer. I know this (it took me a few seconds) but I'm surprised this is allowed to compile! – Richard Birkett Apr 22 '16 at 22:22
  • 2
    To notice this loop, the compiler would have to execute your code, which isn't the compiler's job. Both functions are valid, that's why it compiles. – EmilioPelaez Apr 22 '16 at 22:27
  • The issue is not that there is a loop, but that designated initializers are calling other designated initializers. Even stranger, if `let a: Int` is used, so that `a` has no default value, then the code *still* compiles even though `self` is referenced before `a` is assigned. – BallpointBen Apr 22 '16 at 22:34
  • 3
    Compilers do not detect nor warn against infinite loops. To do so is to solve a very hard problem. https://en.wikipedia.org/wiki/Halting_problem – Reza Shirazian Apr 22 '16 at 22:43