Why does declaring the same function both with and without parameters not cause compilation errors?
Asked Answered
W

2

6

For the code:

int hi(int);
int hi();
int main()
{
    hi(3);
}

I don't get any compilation errors (calling hi(); without arguments does get a compilation error).

I expected that the compiler would complain that the function has already been declared differently. Any idea why this is the behavior?

Whichsoever answered 3/5, 2023 at 6:38 Comment(0)
C
7

You can declare the same symbol as many times as you like, and as long as the declarations don't contradict each other, you won't get an error.

The reason that

int hi();

doesn't contradict

int hi(int);

is because a declaration without any arguments at all means that you say you really don't know how many arguments there are or what types they are. That doesn't really contradict the first declaration. And because you already declared hi, the compiler will simply use that declaration.


As noted in a comment, this will change with the C23 standard. It has adopted the semantics from C++ that no explicit arguments means void, so

int hi();

will be equivalent to

int hi(void);

That of course means that the two declarations will be contradicting each other.

Circumstantiate answered 3/5, 2023 at 6:44 Comment(2)
Note that in C23, the two function declarations will contradict each other. The int hi(); declaration will be like C++ and equivalent to int hi(void);, which will indeed contradict int hi(int);. Until then, this analysis is sound.Digitalis
@JonathanLeffler Ah, so they adopted the C++ semantics for that? Din't know that. Thanks :)Circumstantiate
I
5

You may use several compatible function declarations if among them there is no more than one function definition.

In C there is defined the notion of compatible types.

From the C11 Standard (6.2.7 Compatible type and composite type)

1 Two types have compatible type if their types are the same. Additional rules for determining whether two types are compatible are described in 6.7.2 for type specifiers, in 6.7.3 for type qualifiers, and in 6.7.6 for declarators.

and (6.7 Declarations)

4 All declarations in the same scope that refer to the same object or function shall specify compatible types.

and at last (6.7.6.3 Function declarators (including prototypes))

  1. ... If one type has a parameter type list and the other type is specified by a function declarator that is not part of a function definition and that contains an empty identifier list, the parameter list shall not have an ellipsis terminator and the type of each parameter shall be compatible with the type that results from the application of the default argument promotions.

In the both these function declarations

int hi(int);
int hi();

the return types are compatible (they are the same). And the parameter of the first function declaration has the type int that corresponds to the type of the integer promotions.

From the C11 Standard 6.5.2.2 Function calls)

6 If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions.

If you would write for example

int hi(char);
int hi();

then there are declared two different functions because the type char , the type of the parameter of the first function, does not correspond to a type after default argument promotions.

Another example of declaring two compatible functions and two different functions.

These two declarations declare the same function

int hi( double );
int hi();

and these two declarations declare different (non-compatible) functions

int hi( float );
int hi(); 

In C23 Standard there are done the following changes relative to function declarations

— mandated function declarations whose parameter list is empty be treated the same as a parameter list which only contain a single void;

So according to the C23 Standard these function declarations

int hi(int);
int hi();

are equivalent to

int hi(int);
int hi( void );

So they declare two different functions and the compiler should issue a message.

Isadoraisadore answered 3/5, 2023 at 8:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.