Search code examples
csecurityfunction-declarationfunction-definition

Can declaring a function prototype without parameters create security breaches?


I have heard that calling int main(){...} was bad practice and one should rather call the function with its parameters int main(int argc, char* argv[]){...}, I was wondering if this could be generalized to function declarations in headers.

In some situations, one may have to write a function prototype in a header without any parameters on inputs (for some reasons of include troubles let say), and declare the input parameters and their types in the function definition in a distant .c file. Is this likely to cause security issues as one could make use of this absence of informations? Or is the function definition (with input parameters declared) preventing this? I couldn't find any link about this.


Solution

  • In C when declaring a function prototype without any listed arguments, like in

    voif my_function();  // No specified arguments
    

    the compiler treats it as declaring a function with an unknown amount of arguments of unknown types.

    That means callers could pass whatever arguments they like and the compiler would happily accept it, without any checking about correctness or not (since it's not possible). For the remainder of the translation unit, the arguments used for the first call will be assumed to be the arguments the function takes.

    Now if another translation unit calls the same function with different arguments, you suddenly have mismatching calls. And if even one call doesn't match the actual arguments in the function definition then you will have undefined behavior.


    This is of course different from defining a function without arguments:

    void my_function()
    {
        // Some code...
    }
    

    If the function haven't been otherwise declared yet, then this also declares the function as taking no arguments. This is in effect equivalent to

    void my_function(void)
    {
        // Some code...
    }
    

    Lastly for the main function. It's not allowed to declare a prototype of the main function, only to define (implement) it.

    And int main(void) is a valid variant of the function, which (since a prototype isn't allowed) means that you can use int main() because it's equivalent to int main(void).