Implicit function declarations sometimes work in C?
Asked Answered
Q

4

3

Can someone please explain to me why the following compiles:

int main()
{
    int a = mymethod(0);
}
int mymethod(int b)
{
    return b;
}

but this does not:

int main()
{
    mymethod(0);
}
void mymethod(int b)
{
    return;
}

I thought that forward declarations were required in C/C++, yet here is a counterexample. How do implicit declarations work in C?

Quintonquintuple answered 30/7, 2013 at 3:39 Comment(2)
the error should tell you, should say something like expecting a function returning an int, because that's what it makes a guess as, then it finds its a voidMercurialism
possible duplicate of Are prototypes required for all functions in C89, C90 or C99?Afloat
T
7

I assume when you say that it does not work in the second code example, you mean that you get a compile time error.

The reason is that when there is an implicit function declaration, it is assumed to take a fixed number of arguments, and return int. However, mymethod() is first implicitly declared, and then later declared to return void. This is an error since the new declaration does not match the previous (implicit) declaration.

C90 (ANSI C89) allowed implicit function declarations. From C89, Section 3.3.2.2:

If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier, and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if, in the innermost block containing the function call, the declaration

extern int  identifier();
appeared.

However, this allowance has been removed as of C99 (and hence also disallowed in C11). C++ never allowed implicit function declarations.

Thistledown answered 30/7, 2013 at 3:44 Comment(1)
Furthermore, in both C99 and C11, a call to a function with no visible declaration is a constraint violation. That means that a conforming compiler must issue a diagnostic, but it needn't be a fatal error. Even a conforming C99 compiler can issue a warning and then use the C90 semantics. (gcc -std=c99 -pedantic does this; you need to use -pedantic-errors if you want the error to be fatal.)Ladysmith
V
3

The implicit declarations the compiler generates will assume that the return type of the function is int, which sometimes is not what you want. Avoid using it.

Note that implicit declarations only works in C89, it's removed in C99. C++ doesn't support it either.

This can be confirmed in C11(ISO/IEC 9899:201x) standard.

In the C11 Forward section, it lists all the major changes in the third edition(i.e, C11) and the second edition(i.e, C99), one of which is:

Major changes in the second edition included:

...

— remove implicit function declaration

Also in Rationale for International Standard Programming Languages C §6.5.2.2 Function calls

A new feature of C99: The rule for implicit declaration of functions has been removed in C99. The effect is to guarantee the production of a diagnostic that will catch an additional category of programming errors. After issuing the diagnostic, an implementation may choose to assume an implicit declaration and continue translation in order to support existing programs that exploited this feature.

Vendible answered 30/7, 2013 at 3:46 Comment(0)
S
1

The default assumption is that a function returns an int. So the first one worked (luckily) because that was the case. In general, it does not.

Statecraft answered 30/7, 2013 at 3:43 Comment(0)
C
1

For implicit function in C99 the function has to be declared before it's getting called. While declaring write the proper prototype of functions. The default method declaration prototype has return type "int" that's why it works fine (in first case of your example) with one warning (Like "implicit declaration of a function is invalid in c99"). But in second case you have changed the default prototype so u need to declare its prototype.

For example:

//Function prototype declaration
  void mymethod(int);  

//Implementations
  int main()
  {
    mymethod(0);
  }

  void mymethod(int b)
  {
     return;
  }
Capriccioso answered 30/7, 2013 at 4:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.