André Puel
André Puel

Reputation: 9189

Is it safe to invoke a C function with more parameters than it expects?

I was reading on wikipedia about the cdecl calling convention. Since the parameters are pushed on the stack in reverse order, I believe it is safe to call a C function with more parameters than it expects.

Am I right or did I miss something?

Note: I am not talking about variadic functions.

Upvotes: 2

Views: 196

Answers (4)

imreal
imreal

Reputation: 10378

It is not!!!

This code causes a segmentation fault:

#include <stdio.h>

#define stdcall __attribute__((stdcall))

stdcall void func(int param1, int param2)
{
    printf("%d, %d\n", param1, param2);
}

int main()
{
    void(*f)(int, int, int) = func;
    f(66, 67, 666);
    f(1, 2, 3);

    return 0;
}

This is just an elaboration to what other people have pointed out about calling conventions. I believe a POC helps making a point.

Upvotes: 4

Andreas Wiese
Andreas Wiese

Reputation: 728

I just had a quick look into ISO/IEC 9899 (a.k.a. C99): There's no word about calling conventions anywhere, thus (as suggested in the comments) you should clearly not do this. Even if it might work on a certain architecture, a certain operating system, and a certain version of a certain compiler, there is absolutely no guarantee that it will still work when only one of those parameters changes.

Upvotes: 6

Deduplicator
Deduplicator

Reputation: 45674

You are making one big wrong assumption: The so-called C calling convention is not contractual for C.
While old C compilers were forced to use such a calling convention (even if it was suboptimal), due to there being no function prototypes, modern compilers can (and are allowed to) use more efficient callee-clean calling conventions for all but old-style and vararg functions. Most compilers have a switch to select the standard calling convention used.

Upvotes: 5

abelenky
abelenky

Reputation: 64710

Yes, it is safe, partially for the reason you gave (params pushed in reverse order), and also partially due to the calling convention.

C Calling Convention
The C calling convention is that the Caller cleans up parameters.
(the alternative is that the Callee cleans up).

Because the caller knows how many params it pushed, it will know how many to properly clean up, regardless of how many params the Callee used or expected.


Pushing args in reverse order
When parameters are pushed onto the stack in reverse order, the 1st parameter gets pushed on last. Regardless of how many params were pushed, the Callee always knows where to find param #1, at the top of the stack. (and also param #2, #3, etc).

If the stack convention were reversed, param 1 would be put on the stack first, and could be "buried" by an arbitrary number of subsequent parameters; the Callee would not know how far into the stack to look.

Upvotes: 0

Related Questions