2

I came across the following difference related to function definition/declaration between C and C++.

In C++ if I call a function before declaring and defining it,I get the error message 'function name is invalid identifier' which is fine for me as it sounds reasonable.

In C with Visual Studio compiler when I compiled the following program I get the error message:

error C2371: 'fun' : redefinition; different basic types

and in gcc-4.3.4 it executed successfully with just this warning:

warning: conflicting types for ‘fun’

Here goes the program:

#include <stdio.h>
int main(){
    fun();
    return 0;
}
void fun(){
    printf("It is fun");
}

So is it fine in C to just call a function and later bother about defining it?! And why the compilers behave differently?

unwind
  • 391,730
  • 64
  • 469
  • 606
ZoomIn
  • 1,237
  • 1
  • 17
  • 35

6 Answers6

2

You must declare the function before. If it is not declared, by default the function is supposed to return int and can take any number of arguments.

fge
  • 119,121
  • 33
  • 254
  • 329
  • 2
    In what language? C++ has never supported implicit declaration of functions, and I believe that it was removed from C99 (although what you say was true for earlier versions of C). – James Kanze Dec 14 '11 at 10:29
  • Most c compilers default to c89, sometimes with extensions. – Dave Dec 14 '11 at 10:45
  • Well, in C this is true (for C99 I don't know). It just seems that gcc here is more permissive than Visual Studio, or maybe Visual Studio wants C99? No idea, I only use gcc. – fge Dec 14 '11 at 10:47
  • C99 _is_ C, so you should say "in C89 this is true";) Visual Studio doesn't expect C99, Microsoft explicitly stated they have no intent of supporting C99. Maybe VS compiles it as C++ regardless. – Daniel Fischer Dec 14 '11 at 12:04
2

When you call the function without a prototype in C89 (disclaimer: I don't know about C99), you are implicitly declaring it as

int fun();

Note that in C, other than in C++, the empty parantheses just mean that you haven't specified what arguments it takes, not that it takes zero arguments.

When you redeclare the function as returning void, you get the warning, but no error. If you return something non-trivial (structs, floats, ...) instead of void or if you try to use the int result of the function, then you might be in deep trouble at runtime.

wolfgang
  • 4,883
  • 22
  • 27
  • OK, I don't know at the moment at what point in the development of the C standard this happened, but traditionally, compilers just emitted a warning for the type mismatch, and more "modern" compilers tend to emit an error. Your version of gcc is just trying to be a bit more traditional. – wolfgang Dec 14 '11 at 10:41
  • @ZoomIn: the standard does not require that the compiler rejects code that has errors, it only requires that the errors are diagnosed. gcc issues a warning, so it has diagnosed it. MSVC has chosen to issue an error, which is also fine. If you want gcc to always reject such code, use `-pedantic-errors`. If you also add `-std=c99`, you'll see two errors: the one for the conflicting types that you've had before, and an extra one because implicit declarations are forbidden in C99. – Steve Jessop Dec 14 '11 at 10:41
  • Also, note that it's not exactly "working" in Visual C; it's giving you a warning that you are engaging in undefined behaviour. You are calling a function and expecting an int return value, which ends up to be an undefined value because the function doesn't return an int, and luckily you don't use the value. – wolfgang Dec 14 '11 at 10:44
  • Ok so implicit declaration happens if we do not declare the function before using it(returning int and taking undefined number of parameters) in C89 and some compilers allow this with warnings and some strictly give the error.In C99 implicit declaration are denied.So this code wont work in C99 and gives error like Cpp.Thank you all,I got it now. – ZoomIn Dec 14 '11 at 11:06
1

C supports 'implicit int' return type i.e fun(); would be treated as a declaration of a function fun taking no arguments and returning an int. This is because you have not declared the function before.

This is not the case in C++ wherein your code is ill-formed.

Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
1

This will only reliably work in C when the function has no parameters and returns int so yes, it is portable, but a very bad practice - here's a very good example explaining why.

Community
  • 1
  • 1
sharptooth
  • 167,383
  • 100
  • 513
  • 979
1

Your code is invalid for C++ (as others said already) and also for C99. None of them allows implicit declaration of functions.

There is not much reason to allow such a thing, it is not very difficult to maintain a header file that contains the prototype of the functions that you use.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
0

The problem is that the declaration of fun() and its implementation differ in its return type:

fun()   /* int return type assumed */

/* ... */

void fun() { /* ... */ }   /* void "return type" */

However, in the standard C++ ISO 98 it was stated that the compiler should not assume int type for missing types anymore (not sure about C'99, while you post your question for C AND C++).

Finally, declaring a function inside main() is possible, but not a good common practice, unless the function fun() should not be known to the rest of the program.

Baltasarq
  • 12,014
  • 3
  • 38
  • 57