Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C function call with too few arguments

I am working on some legacy C code. The original code was written in the mid-90s, targeting Solaris and Sun's C compiler of that era. The current version compiles under GCC 4 (albeit with many warnings), and it seems to work, but I'm trying to tidy it up -- I want to squeeze out as many latent bugs as possible as I determine what may be necessary to adapt it to 64-bit platforms, and to compilers other than the one it was built for.

One of my main activities in this regard has been to ensure that all functions have full prototypes (which many did not have), and in that context I discovered some code that calls a function (previously un-prototyped) with fewer arguments than the function definition declares. The function implementation does use the value of the missing argument.

Example:

impl.c:

int foo(int one, int two) {
  if (two) {
      return one;
  } else {
      return one + 1;
  }
}

client1.c:

extern foo();
int bar() {
  /* only one argument(!): */
  return foo(42);
}

client2.c:

extern int foo();
int (*foop)() = foo;
int baz() {
  /* calls the same function as does bar(), but with two arguments: */
  return (*foop)(17, 23);
}

Questions: is the result of a function call with missing arguments defined? If so, what value will the function receive for the unspecified argument? Otherwise, would the Sun C compiler of ca. 1996 (for Solaris, not VMS) have exhibited a predictable implementation-specific behavior that I can emulate by adding a particular argument value to the affected calls?

like image 946
John Bollinger Avatar asked Jul 11 '13 21:07

John Bollinger


People also ask

What does too few arguments to function mean in C?

error: too few arguments to function(.......) means you are passing fewer arguments than the parameters. You should pass an equal parameter as your function hold. If your function holds three parameters then you must input three parameters for calling the function.

What does it mean to have too few arguments to call a function?

At times, you may have noticed an error “You've Entered Too Few Arguments For This Function” while working with Excel. It mainly happens when you don't fill up the required spaces for the arguments to perform a function in an Excel formula.

How many arguments can be used in a function in C?

The maximum number of arguments (and corresponding parameters) is 253 for a single function. Arguments are separated by commas. However, the comma is not an operator in this context, and the arguments can be evaluated by the compiler in any order.

What does too many arguments mean in C?

the too many arguments to function Error in C++ Arguments are values that are defined when a function is called. The too many arguments to function error occur because of these arguments in a function. The number of arguments should be the same in the function call and the function declaration of a program.


2 Answers

EDIT: I found a stack thread C function with no parameters behavior which gives a very succinct and specific, accurate answer. PMG's comment at the end of the answer taks about UB. Below were my original thoughts, which I think are along the same lines and explain why the behaviour is UB..

Questions: is the result of a function call with missing arguments defined?

I would say no... The reason being is that I think the function will operate as-if it had the second parameter, but as explained below, that second parameter could just be junk.

If so, what value will the function receive for the unspecified argument?

I think the values received are undefined. This is why you could have UB.

There are two general ways of parameter passing that I'm aware of... (Wikipedia has a good page on calling conventions)

  1. Pass by register. I.e., the ABI (Application Binary Interface) for the plat form will say that registers x & y for example are for passing in parameters, and any more above that get passed via stack...
  2. Everything gets passed via stack...

Thus when you give one module a definition of the function with "...unspecified (but not variable) number of parameters..." (the extern def), it will not place as many parameters as you give it (in this case 1) in either the registers or stack location that the real function will look in to get the parameter values. Therefore the second area for the second parameter, which is missed out, essentially contains random junk.

EDIT: Based on the other stack thread I found, I would ammended the above to say that the extern declared a function with no parameters to a declared a function with "unspecified (but not variable) number of parameters".

When the program jumps to the function, that function assumes the parameter passing mechanism has been correctly obeyed, so either looks in registers or the stack and uses whatever values it finds... asumming them to be correct.

Otherwise, would the Sun C compiler of ca. 1996 (for Solaris, not VMS) have exhibited a >> predictable implementation-specific behavior

You'd have to check your compiler documentation. I doubt it... the extern definition would be trusted completely so I doubt the registers or stack, depending on parameter passing mechanism, would get correctly initialised...

like image 76
Jimbo Avatar answered Oct 05 '22 14:10

Jimbo


If the number or the types of arguments (after default argument promotions) do not match the ones used in the actual function definition, the behavior is undefined.

What will happen in practice depends on the implementation. The values of missing parameters will not be meaningfully defined (assuming the attempt to access missing arguments will not segfault), i.e. they will hold unpredictable and possibly unstable values.

Whether the program will survive such incorrect calls will also depend on the calling convention. A "classic" C calling convention, in which the caller is responsible for placing the parameters into the stack and removing them from there, will be less crash-prone in presence of such errors. The same can be said about calls that use CPU registers to pass arguments. Meanwhile, a calling convention in which the function itself is responsible for cleaning the stack will crash almost immediately.

like image 42
AnT Avatar answered Oct 05 '22 14:10

AnT