| > Did you even try my example? No compiler warnings are generated (nor should the be). Only because it managed to match on a defined method type. If a class declaration hadn't been found at compile time with the given declared method, it would have issued a warning. If the match was ambiguous and the types incorrect, it would have emitted incorrect code, and possibly a warning (or always, with -Wstrict-selector-match). > What do you mean by defined method types? It is simply looking for any selector which matches on any class because there is not enough statically available information to know any different. By 'defined method types', I mean methods declared on visible classes that match the given selector. If it matches on the wrong one, the wrong dispatch function and/or the wrong function call epilogue will be emitted. Method calls are ABSOLUTELY NOT ABI identical for all possible types. I can't possibly emphasize this enough. For example: - (void) performWithObject: (NSObject *) object;
- (void) performWithObject: (NSObject *) firstObj, ...;
The instructions emitted for a vararg dispatch ARE NOT the same as the non-vararg dispatch on all platforms, and incorrect method selection will result in undefined behavior on dispatch.> Are you familiar with NSInvocation? Or performSelector:, performSelector:withObject:, performSelector:withObject:withObject:? Or NSNotificationCenter's addObserver:selector:name:object:? This is all done at runtime. > No special type information is available to the compiler when using these. Yes, it is. Methods have associated type encodings that describe the return and argument types, and that's used to perform runtime dispatch with NSInvocation. This is why NSInvocation is so slow -- similar to libffi, it must evaluate the types and construct the call frame at runtime. It does this by evaluating the type data associated with method implementations by the compiler. Methods such as performSelector rely on specific type conventions (such as void return, optional single object argument) and will fail if used with targets that do not match the expected convention. |
Of course IMPs aren't identical if they take different parameters. This doesn't affect interchanging Objective-C types though. Yes, the arity and order are important, but the compiler doesn't enforce anything beyond that a pointer is passed for id types.