Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The reason why it was generally not used in C was probably that in pre-ANSI C, prototypes were optional, calling conventions were enforced loosely, and even in functions that were not officially variadic, sometimes trailing arguments were omitted deliberately or accidentally.


Prototypes did not exist in original K&R. Even function declarations (without prototypes/parameter lists) were still optional in C89 (“ANSI C”), only C99 disallowed calling undeclared functions. To this day, GCC accepts call to undeclared functions by default. Generally, the ABIs GCC supports are carefully constructed to support such usage in many historically important cases (such as calling functions declared in <unistd.h>, many of which use the default int return type, too).

The K&R legacy is likely the reason for the caller-pops-arguments convention, but there was also a time where it was deemed more efficient because you could combine multiple stack adjustments.

There's also a neat trick I learned from LuaJIT: if you store the stack pointer in a callee-saved register before the call and restore it afterwards, it works with both conventions.


Ah yes you're right. I had forgotten just how primitive declarations in K&R C were; I thought parameter names were allowed.

In addition to caller-pops-arguments, I also remember that arguments used to be pushed on the stack in right to left order, so the callee had a fixed offset to the first argument, no matter how many arguments were provided.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: