Strange C Function Syntax

The other day I saw some code C which I thought to be clearly wrong:

double square(x)
    double x;
{
    return x * x;
}

I mean, that just cannot compile, right? What in the world is that to mean, anyway?

Let's embed that in a minimal working (?) example:

#include <stdio.h>

double foo(x)
    double x;
{
    return x * x;
}

int main()
{
    printf("%g\n", foo(2.5));
    return 0;
}

And here is what you get:

$ gcc -Wall -Wpedantic crap.c
$ ./a.out 
6.25

With GCC 6.3 and a lot of warnings, this is just fine! And the program produces a sensible result. Also Clang does not find anything particularly wrong with it, even when I enabled every warning that there is:

$ clang -Weverything crap.c 
crap.c:4:8: warning: no previous prototype for function 'foo' [-Wmissing-prototypes]
double foo(x)
       ^
1 warning generated.

This just means that we don't have a header file, but that's not what this is about.

This peculiar syntax is allowed in C and one can declare the types of the parameters between the function declaration and the body. I would not want to have it in my programs, but apparently the C compiler will just read it. Perhaps the only solace is that this is not possible in C++:

$ g++ -Wall -Wpedantic crap.c
crap.c:4:12: error: 'x' was not declared in this scope
 double foo(x)
            ^
crap.c:6:1: error: expected unqualified-id before '{' token
 {
 ^
crap.c: In function 'int main()':
crap.c:12:27: error: 'foo' cannot be used as a function
     printf("%g\n", foo(2.5));
                           ^