I've been hit by some weird behaviour recently that caused me to tear my hair out a little. I think I've finally worked out the problem and understand the cause but would like a sanity check on my conclusions. I'll skip the problem and just state my assertion for simplicity (the back story is long and tedious).
All this is occuring on both OSX and the iOS simulator (I'd imagine the same is true for on device, but I haven't tested that).
- dylib A: Exports function
foo
marked as weak. - dylib B: Exports function
foo
not marked as weak. - Application X: linked against dylib A.
The application runs (dylib A is automatically loaded) and calls foo
. A::foo
(excuse the notation abuse) is called. The application then loads dylib B. The symbol for foo
is rebound to B::foo
. Subsequent calls to foo
always call B::foo
, furthermore foo
can never be rebound as dylib B defines foo
to be strong.
Correct?
As I write this, logically I can only conclude that it must be (indeed I've verified this behaviour with an example). The behaviour is effectively the same as what happens during static linking. My surprise was that dynamic rebinding could actually occur, as you can imagine that it could lead to some weird behaviour if a function can change implementation part way through execution.
N.B. I stubled over this when overriding operator new
in a dylib. Since libc++ (implicitly) exports operator new
as weak the scenario above arose.
Presumably the moral is that if you use weak dynamic symbols then you must be very sure you know what you're doing :)