Consider the following code:
#include <iostream>
typedef int (*test_func_t) (int, int, int);
int print_integer (int a)
{
std::cout << "num: " << a << "
";
return a;
}
int main (int argc, char * argv[])
{
test_func_t func = (test_func_t) &print_integer;
std::cout << "calling with 3 parameters func(5,7,9)
";
func(5,7,9);
return 0;
}
As you can see, a type (test_func_t) is defined as a function with 3 int arguments. A function pointer (func) is assigned with a pointer to "print_integer", which receives only 1 argument, and the function pointer is then called with 3 arguments (5, 7, 9).
This code works and produces "num: 5" output.
gdb disas output (Intel syntax)
disas main
...
0x080486cb <+9>: mov DWORD PTR [esp+0x1c],0x804867d
...
0x080486e0 <+37>: mov DWORD PTR [esp+0x8],0x9
0x080486e8 <+45>: mov DWORD PTR [esp+0x4],0x7
0x080486f0 <+53>: mov DWORD PTR [esp],0x5
0x080486f7 <+60>: mov eax,DWORD PTR [esp+0x1c]
0x080486fb <+64>: call eax
disas print_integer
...
0x08048683 <+6>: mov DWORD PTR [esp+0x4],0x8048830
0x0804868b <+14>: mov DWORD PTR [esp],0x8049ae0
0x08048692 <+21>: call 0x8048530 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)@plt>
0x08048697 <+26>: mov edx,DWORD PTR [ebp+0x8]
0x0804869a <+29>: mov DWORD PTR [esp+0x4],edx
0x0804869e <+33>: mov DWORD PTR [esp],eax
0x080486a1 <+36>: call 0x80484d0 <std::ostream::operator<<(int)@plt>
As you can see, the rest of the arguments ([ebp+0x12] and [ebp+0x16]) are simply not used.
My questions:
- This seems to work on Linux x86 with __cdecl calling convention. Is it safe on other architectures and calling conventions as well?
- Does any C/C++ standard allows/defines the result of assigning a function pointer from a function that expects fewer arguments?
Example of such use: node.js's NODE_MODULE registers a function whose type has 3 arguments [exports, module, priv]. It is called with those 3 but formal examples show registering of a function with 1 or 2 arguments.
See Question&Answers more detail:
os