8

When a function call is made in C, the arguments are passed in the reverse order. This is important so that we have access to the first argument. And this some how supports varargs. I don't understand that even if you have access to the first argument, you would still need to know how many arguments the function has, otherwise you might easily slip past the last argument and start considering invalid values as arguments.

And if the argument count is required, then there is no point in passing arguments in the reverse order because you can access the first argument with (sp - 2 * number_of_arguments, sp = stack pointer.

Passing arguments in the reverse order is also supposed to help recursive calls, I don't understand how.

Thank you in advance.

Flow
  • 23,572
  • 15
  • 99
  • 156
user590849
  • 11,655
  • 27
  • 84
  • 125
  • Could you provide a reference to this? – Karthik T Sep 09 '13 at 01:24
  • Also, vararg handling requires 1 non vararg arguement, I guess that is used as a sentinel if they are coming from the end to the begining – Karthik T Sep 09 '13 at 01:25
  • reference meaning ? I am talking about function calling in C. – user590849 Sep 09 '13 at 01:27
  • 2
    You can think of them as reverse order, but in reality they're being pushed right to left onto the stack. – Scotty Bauer Sep 09 '13 at 01:33
  • Sorry for the ambiguity, reference meaning some documentation that talks about this, possibly the source that you got it from – Karthik T Sep 09 '13 at 01:33
  • Why do you care? Are you trying to implement a different language that is ABI compatible with C? The C standard doesn't mention anything about how the arguments are actually passed, just that the order they appear in the caller will be converted to the matched arguments in the function declaration. – jxh Sep 09 '13 at 01:35
  • @jxh curiosity isn't a bad thing – Karthik T Sep 09 '13 at 01:38
  • @KarthikT: I am not questioning that, I am asking for clarification to ascertain the best way to resolve the question. As it is written, this is a platform specific question, and not a general C question. But, there may be a general C solution to the problem being solved. – jxh Sep 09 '13 at 01:59

2 Answers2

11

C does not define the order in which arguments are passed. In fact, some very common calling conventions (like the x86-64 SYSV ABI) pass the first several arguments in registers, with no order at all.

However, it is true that it is very common for variable-argument-list functions to have their argument pushed onto the stack from last to first. This is because the code emitted for the called function has to work with any number of additional arguments passed. You are right that the calling convention could include passing the number of additional arguments - but passing the arguments in reverse order means that this is not required, so it is a simpler option. You are correct that it is easy under this scheme to start examining values beyond the last argument passed - this is what tends to happen for example if you pass insufficient arguments to printf() for a given format string.

Functions with a fixed number of arguments can be passed in either order, and in fact left-to-right calling conventions do exist (the 16-bit Windows API used such a calling convention).

caf
  • 233,326
  • 40
  • 323
  • 462
  • So how is the not reading of invalid values handled in cases where arguments are passed in reverse order ? – user590849 Sep 09 '13 at 02:00
  • 1
    @user590849: It's not - it's up to the function and its caller to do the right thing (for example, `printf()` is written to only access variable arguments corresponding to format specifiers in the format string, and the caller of `printf()` is reponsible for supplying an argument for each format specifier it uses). – caf Sep 09 '13 at 03:25
  • "include passing the number of additional arguments - but passing the arguments in reverse order means that this is not required" I don't see how "passing" the arguments in reverse order allows the compiler to omit the number of vargs. Could you elaborate that? – Flow Nov 14 '17 at 22:36
  • @Flow: If the arguments are pushed to the stack in reverse order, then when the called function looks back up the stack it sees the arguments in their natural order - each call to `va_arg()` can just look a bit further up the stack. – caf Nov 14 '17 at 22:52
  • Right, but that was not the question. Why does reverse order allow you to ommit the number of var args, and not non-reverse order. I assume the Callee could in both cases just walk the stack until the base/frame pointer is reached. – Flow Nov 14 '17 at 23:26
  • @Flow: The caller function is not guaranteed to have used a frame pointer at all, and even if it has, the caller can't tell the difference between the caller's local variables and the function arguments being passed. – caf Nov 15 '17 at 00:02
  • Arguments are stored in the caller's frame, not the callee's. It's impossible to determine how many arguments were passed. – jv110 Jul 14 '18 at 06:59
0

In theory there is no preference to how a compiler generates code to store parameters on a stack or in registers. It really depends on the architecture of the target machine.

Having said that, where did you get the idea that they had to be in reverse order. A citation would be nice to evaluate your question.

So, the real answer, is it depends on what the compiler writer wishes to do.

finally, note this is analogous to Reverse Polish Notation: AB+ means A+B or Prefix Notation where +AB means A+B. Thus, so long as the compiler is consistent then ordering is immaterial.

JackCColeman
  • 3,777
  • 1
  • 15
  • 21