3

What happens if I pass more arguments than required to a function? I expected something to be corrupted in the called function, but everything works fine in some small test codes.

eg:

void print()
{
    int x=10;
    printf("%d\n",x);
}
void main()
{
    print(0,0,0,0,0);
}
vpillai
  • 374
  • 1
  • 3
  • 15
  • Perhaps this answers what you want: http://stackoverflow.com/questions/51032/is-there-a-difference-between-foovoid-and-foo-in-c-or-c – SidR Jun 14 '13 at 09:09
  • 4
    Just as a habit, in C never declare or define functions with `()`. Always use `(void)` for empty parameters lists. Then your kind compiler will eagerly explain you that you did something wrong. – Jens Gustedt Jun 14 '13 at 09:20
  • 1
    Also C11 6.11 "Future language directions" labels this as obsolete behavior that might not compile in future versions of the C standard. `"The use of function declarators with empty parentheses (not prototype-format parameter type declarators) is an obsolescent feature."` – Lundin Jun 14 '13 at 09:40
  • @JensGustedt Ah! good point. But, then that is not applicable when I work with libraries. Basically, if print was provided as a .o without a header file, then I will still be able to call print with many arguments and link it. – vpillai Jun 14 '13 at 09:42
  • As from the below answer, I understand it is undefined in C specification. But, I am still curious to know what happens specifically in GCC. – vpillai Jun 14 '13 at 09:45
  • 1
    @vpillai, what happens specifically on any given architecture depends on the calling convention that this architecture uses. Some may e.g place all parameters on the stack, others have the first arguments (if of adequate type) may pass them in hardware registers. In both cases you may have trouble since one end might access things that the other end doesn't expect. Also have in mind that if no prototype is known, all arguments of "narrow" type are expanded to `int`, so there might really weird things be going on. – Jens Gustedt Jun 14 '13 at 09:59

3 Answers3

5

It is undefined behavior.

(C99, 6.5.2.2p6) "If the expression that denotes the called function has a type that does not include a prototype, [...] If the number of arguments does not equal the number of parameters, the behavior is undefined."

And we know from 6.9.1p7 that print function does not provide a prototype.

C99, 6.9.1p7) "If the declarator includes a parameter type list, the list also specifies the types of all the parameters; such a declarator also serves as a function prototype for later calls to the same function in the same translation unit. If the declarator includes an identifier list,142) the types of the parameters shall be declared in a following declaration list."

As there is no constraint violation, no diagnostic message is required.

ouah
  • 142,963
  • 15
  • 272
  • 331
  • ok. But, any idea where all the zeros I pass will be placed ? (Maybe, an answer specific to GCC) – vpillai Jun 14 '13 at 09:04
  • 4
    @vpillai undefined is undefined but an assembly dump with `gcc` shows they are pushed in the stack. – ouah Jun 14 '13 at 09:07
  • Actually my doubt came from that. will it not overwrite the local variables of print? – vpillai Jun 14 '13 at 09:13
  • @vpillai again undefined is undefined, you should not do it and it can overwrite anything. – ouah Jun 14 '13 at 09:15
  • 2
    @ouah where the arguments go is ABI-dependent. On my x86_64, they are passed in registers. – Daniel Fischer Jun 14 '13 at 09:47
  • @DanielFischer yes, thanks for the precision. I should have mentioned an "assembly dump on my implementation". – ouah Jun 14 '13 at 09:50
2

On a function call, the compiler will decide to put the arguments in the CPU register if they fit, otherwise, the arguments will go to the STACK memory (http://www.technochakra.com/wp-content/uploads/assembly_stack.jpg).

When you add arguments that doesn't exist, it may lead to undefined behavior since the called function code may missalign the stack memory access. In other words, the calling code will write the stack with a different layout of the expected layout inside the function.

Felipe Lavratti
  • 2,887
  • 16
  • 34
-1

A compile error will encounter. I compile the code in visual c++ 6.0, the compile output:

error C2660: 'print' : function does not take 5 parameters
Charles0429
  • 1,406
  • 5
  • 15
  • 31
  • but in GCC, compilation error happens only if I have a prototype for the function. – vpillai Jun 14 '13 at 09:11
  • 1
    This is irrelevant. First: you are compiling with a C++ compiler. Second: said compiler is notorious for its very poor C standard compliance. – Lundin Jun 14 '13 at 09:39