From my understanding of the bare metal, though, I believe the argument would be placed on the stack, and have no idea how the runtime would know that it should be discarded.
You are correct, the caller places the argument on the stack. After the call returns the caller removes the arguments it placed on the stack, so discarding any extra arguments the callee doesn't expect is not an issue.
However that is not enough to know your code will work, the callee needs to know where the arguments are on the stack. The stack usually grows downwards as items are pushed onto it and the callee locates arguments as positive offsets from the stack pointer. If arguments are pushed left-to-right then the last argument is at the smallest offset from the stack pointer, the first at the largest offset. If additional arguments are pushed in this scenario then the offsets to the expected arguments would all change. However (Objective-)C supports variadic functions, those that take an unspecified number of arguments (think printf
, stringWithFormat:
, etc.), and so arguments in a call are pushed right-to-left, at least for variadic functions, so that the first argument is the last pushed and hence at a known constant offset from the stack pointer regardless of how many arguments are pushed.
Finally an Objective-C method call is translated into a call to a runtime function, objc_msgSend()
, which implements the dynamic method lookup. This function is variadic (as different messages take different numbers of arguments).
So your Objective-C method call becomes a call to a variadic runtime function, and if you supply too many arguments they are ignored by the callee and cleared up by the caller.
Hope all that makes sense!
Addendum
In the comments @newacct has correctly pointed out that objc_msgSend
is not variadic; I should have written "effectively variadic" as I was blurring details for simplicity. They also argued that it is a "trampoline" and not a function; while this is technically correct a trampoline is essentially a function which jumps to other code rather than returning directly, that other code doing the return back to the caller (this is similar to what tail call optimisation does).
Back to "essentially variadic": The objc_msgSend
function, like all functions which implement Objective-C methods, take a first argument which is the object reference the method is being called on, a second argument which is the selector of the desired method, and then in order any arguments the method takes - so the call takes a variable number of arguments but is not strictly a variadic function.
To locate the actual method implementation to invoke at runtime objc_msgSend
uses the first two arguments; the object reference and the selector; and performs a lookup. When it locates the appropriate implementation it jumps/tail calls/trampolines to it. As objc_msgSend
cannot know how many arguments have been passed until it has examined the selector, which is the second argument, it needs to be able to locate the second argument at a known offset from the stack pointer, and for this to (easily) possible arguments must be pushed in reverse order - just as with a variadic function. As the arguments are pushed by the caller in reverse order they have no impact on the callee and additional ones will be ignored and harmless provided the caller is responsible for removing the arguments after the call.
For variadic functions the caller has to be the one which removes the arguments, as only it knows how many are passed, for non-variadic functions the callee could remove the arguments - and this includes the callee that objc_msgSend
tail calls - but many compilers, including Clang, have the caller remove them.
So the call to objc_msgSend
, which is the compilation of a method call, will under Clang ignore any extra arguments by essentially the same mechanism as variadic functions do.
Hope that makes it clearer and doesn't add confusion!
(Note: In practice some arguments may be passed in registers and not on the stack, this does not have significant impact on the above description.)