4 ms·
I mean, you have seen how printf uses %d for char, short and int as a formatter?
by emilfihlman 7y ago
I mean, you have seen how printf uses %d for char, short and int as a formatter?
- dahart 7y agoYeah, of course, but that doesn’t by itself lead me to the conclusion that those are all first converted to another type before being passed on the stack. They could be passed as-is and type-cast inside the printf implementation. The more interesting printf example would be %f, since according to what I learned today, it’s not a float, it’s a double. Are you saying you already knew doubles were passed in variadics instead of float, and the reason you knew is printf?
- microtherion 7y ago> They could be passed as-is and type-cast inside the printf implementation. How would you know what to type-cast FROM? It's not like C compilers pass type information around, nor are C values self describing. > Are you saying you already knew doubles were passed in variadics instead of float, and the reason you knew is printf? I can't speak for the person you're answering to, but in pre-ANSI C, these promotions were ubiquitous (since there were no function prototypes yet), so programmers were very likely to have heard about them at some point.
- boulos 7y ago> How would you know what to type-cast FROM? It's not like C compilers pass type information around, nor are C values self describing. That happens to be true, but one could imagine a calling convention that does do this, e.g. something like: fixed0, fixed1, ..., fixedN, numVarArgs, type0, ..., typeM, arg0, ..., argM it's just that it burns tons more registers than the promotion scheme does. And you'd still end up with a mini "interpreter" in the callee to at least switch over types.
- dahart 7y agoI’d be fibbing if I said I’d thought it out that far before commenting... :P But thank you for offering a plausible explanation, Solomon.
- boulos 7y agoNo problem, Dave! I had to do precisely this for PHP’s variadic arguments. I think HHVM made up even more calling conventions. Fwiw, the next optimization is to “compress” the type signatures into a handful of bits, to save registers. But it’s still not that big of a safety win for actual C code because of the clumsy switch inside the callee.
- boulos 7y agoI know from having to implement va_start/va_arg/va_end and it comes down to ABI. The challenge is how you would have either the caller or callee have a consistent piece of code for pushing/popping the stack. The int case is pretty clear, because whatever you go with a 32-bit register like most args in the C-family of ABIs, and it only matters for the register pressure (you're really just zero extending for char and short). I do find the float/double case clumsy, as is the int64 case, but it falls out of the rules for casting as mentioned and the ABI churn for both floating point and AMD64.