Why does gcc allow arguments to be passed to a function defined to be with no arguments?

I don't get why does this code compile?

#include <stdio.h>
void foo() {
    printf("Hello\n");
}

int main() {
    const char *str = "bar";
    foo(str);
    return 0;
}

gcc doesn't even throw a warning that I am passing too many arguments to foo(). Is this expected behavior?


In C, a function declared with an empty parameter list accepts an arbitrary number of arguments when being called, which are subject to the usual arithmetic promotions. It is the responsibility of the caller to ensure that the arguments supplied are appropriate for the definition of the function.

To declare a function taking zero arguments, you need to write void foo(void);.

This is for historic reasons; originally, C functions didn't have prototypes, as C evolved from B, a typeless language. When prototypes were added, the original typeless declarations were left in the language for backwards compatibility.

To get gcc to warn about empty parameter lists, use -Wstrict-prototypes:

Warn if a function is declared or defined without specifying the argument types. (An old-style function definition is permitted without a warning if preceded by a declaration which specifies the argument types.)


For legacy reasons, declaring a function with () for a parameter list essentially means “figure out the parameters when the function is called”. To specify that a function has no parameters, use (void).

Edit: I feel like I am racking up reputation in this problem for being old. Just so you kids know what programming used to be like, here is my first program. (Not C; it shows you what we had to work with before that.)