Answer to Exploring function calls
The reason for this lies in how calling conventions are implemented. On x86 systems, the
standard one is cdecl, partly because it supports variable number of arguments. In cdecl,
the caller allocates the parameters on the stack, and it is the callers responsibility to
clean up the stack later on. This is good since the caller is then able to pass any number
of parameters to a function, and the called function does not have to know exactly how many
since it is not in charge of cleaning up the stack anyway.
This changed with C++. C++ brought destructors into the picture. Initially I thought that
since cdecl specifies that the caller is responsible for cleaning up the stack, the
caller would also be responsible for destroying any objects that were passed on the stack as
well. It turns out this is not the case. Instead the called function runs the destructor
on the parameters, and then the caller frees the memory from the stack. This means that
we have actually lost the ability of variable parameter lists (until C++11 re-introduced them)
in C++. Yet they are used. How does this work?
It turns out that this is the reason (i guess) why GCC disallows passing other types than
"trivially copyable" types into variable argument lists. If it would allow that, then
it would not be possible to run the correct destructor on the object later on, which would
violate the guarantee of the destructor being called exactly once (unless these calls were
treated specially, of course). Visual Studio has taken another approach instead. That compiler
will silently pass a reference to the object instead ("easily" seen if you read the disassembly
output from the compiler ☺). The va_arg macro correctly handles
this, but we avoid one copy and lose the by-value semantics.
The solution for GCC would therefore be to pass the parameters by pointer (or reference), and by that we would get the same behaviour there as well.
Comments
New comment
You can use GitHub flavored markdown here. Parsed by Parsedown, which does not support all of GitHub's features. For example, specifying the language of code listings is not supported.