How come that in C declaring a variable between a function name and the function block compiles as valid?

731 views Asked by At

At C lang FAQ I found the following code:

void f(ipp)
int **ipp;
{
    static int dummy = 5;
    *ipp = &dummy;
}

I tested compiling it with -Wall -std=c11 -pedantic flags, and it compiled with no warnings or errors. How is that possible - a variable declared between the function name and its block?

Edit:

A few hours after posting, and after a number of answers, I find the question is closed as a duplicate. I don't agree with the decision to close. In fact, the duplicate Q&A and the answers given here so far, although broadly correct, don't answer my question specifically.

My query is about variable declarations appearing between a function name and its block. OK, that's the original K&R style, but I still find the location of the declarations shocking. Having read the K&R Second Edition book that describes ANSI C89, I was aware that the previous style allowed a different way of declaring function parameters, but AFAIK that book did not show the declarations being made in this way. Maybe it does and I have forgotten about it.

I believe it is good to have a question separately about this particular issue in case someone else gets thrown by it in the future. My question should stand for anyone who can shed some light on how it was decided to allow the parameters be declared in this strange location. The impression you get from C and all C-inspired languages is that nothing comes between a token and its block braces. My question draws attention to a significant exception that should be highlighted and its rationalle understood, even if it is 30/40 years old.

Edit 2:

I now find that C++ syntax allows for a token to come between the function name and its block. Even so, the idea of whole declaration lines coming in between is more severe and worth pointing out to C newbies as a quirk they might encounter. I have checked, and the K&R Second Edition book indeed does not explicitly mention this.

4

There are 4 answers

1
Sourav Ghosh On

It's not any variable, it's the function argument. Just another programming style, called K&R style.

Some additional read on this.

1
Jens Gustedt On

This syntax is deprecated since a long time but in C17 it is still valid. The removal of this feature has recently been voted into C2x, see point 6.30:

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2451.pdf

0
Vlad from Moscow On

In general the function definition is defined in the C Standard the following way

function-definition:
    declaration-specifiers declarator declaration-listopt compound-statement

declaration-list:
    declaration
    declaration-list declaration

Such a function definition that contains the declaration-list is named as a function definition with an identifier list opposite to the function definition with a parameter type list.

So in the function declarator there is used a list of identifiers

void f(ipp)
       ^^^^

that need to be declared before the body of the function

void f(ipp)
int **ipp;
^^^^^^^^^

It is an old style of function definitions that is not recommended to use because such definitions do not provide a function prototype that can be checked by the compiler.

0
machine_1 On

From the C11 standard:

6.7.6 Declarators:
1.direct-declarator (parameter-type-list)
2.direct-declarator (identifier-list)

As you can see, the standard specifies two ways of declaring functions.

The first involves typed parameters where each parameter is given a specific type.

The second involves an identifier list where parameter names are supplied inside the enclosing parenthesis without being given data types.

As a result, your code is valid C11 and compiles fine as it should be expected.