Search code examples
coptimizationcompilationstandardsfunction-parameter

Is C compiler allowed to optimize away unused function arguments?


I know that how arguments are passed to functions is not part of the C standard, and is dependent on the hardware architecture and calling convention.

I also know that an optimizing compiler may automatically inline functions to save on call overhead, and omit code that has no "side effects".

But, I have a question about a specific case:
Lets say there is a non trivial function that can not be inlined or removed, and must be called, that is declared to take no arguments:

int veryImportantFunc() {
    /* do some important stuff */

    return result;
}

But this function is called with arguments:

int result = veryImportantFunc(1, 2, 3);

Is the compiler allowed to call the function without passing these arguments?

Or is there some standard or technical limitation that would prevent this kind of optimization?

Also, what if argument evaluation has side effects:

int counter = 1;
int result = veryImportantFunc(1, ++counter, 3);

Is the compiler obligated to evaluate even without passing the result, or would it be legal to drop the evaluation leaving counter == 1?

And finally, what about extra arguments:

char* anotherFunc(int answer) {
    /* Do stuff */

    return question;
}

if this function is called like this:

char* question = anotherFunc(42, 1);

Can the 1 be dropped by the compiler based on the function declaration?

EDIT: To clarify: I have no intention of writing the kind of code that is in my examples, and I did not find this in any code I am working on.
This question is to learn about how compilers work and what the relevant standards say, so to all of you who advised me to stay away from this kind of code: thank you, but I already know that.


Solution

  • To begin with, "declared to take no arguments" is wrong. int veryImportantFunc() is a function accepting any arguments. This is obsolete C style and shouldn't be used. For a function taking no arguments, use (void).

    Is the compiler allowed to call the function without passing these arguments?

    If the actual function definition does not match the number of arguments, the behavior is undefined.

    Also, what if argument evaluation has side effects

    Doesn't matter, since arguments are evaluated (in unspecified order) before the function is called.

    Is the compiler obligated to evaluate even without passing the result, or would it be legal to drop the evaluation leaving counter == 1?

    It will evaluate the arguments and then invoke undefined behavior. Anything can happen.

    And finally, what about extra arguments:

    Your example won't compile, as it isn't valid C.