Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Anybody knows why is this compiling successfully?

Tags:

c

Anybody knows why is this compiling successfully in C?

int main(){
     display();
   return 0;
 } 

 void display(){
     printf("Why am I compiling successfully?");
 }

I thought when declaration is not provided C assume extern int Function_name(arg1,arg2,...){}. Thus this should give an error but however it's working! I know that Ideone is supressing the warnings but my question is why is it just not giving a straight error? (however in C++ it's straight error)

like image 560
Quixotic Avatar asked Nov 19 '12 12:11

Quixotic


4 Answers

Turn up the warning level in your compiler and you should get 2 warnings,

display not declared, int assumed

and

display redeclared

Edit:

Older versions of C (pre C99) aren't really that bothered about return types or argument types. You could say it's part of the K&R legacy. For instance, if you don't explicitly specify the argument types, the compiler won't check them at all.

C++ is stricter, which IMO is a good thing. I always provide declarations and always specify the argument lists when I code in C.

like image 84
Klas Lindbäck Avatar answered Nov 07 '22 18:11

Klas Lindbäck


It's compiling because C uses a lot of defaults to be backwards compatible. In K&R C, you couldn't specify function prototypes, so the compiler would just assume that you know what you're doing when you call a function.

Later (at least ANSI C, but maybe even in C99), C didn't really have a way to distinguish

void display(void);
void display();

so the empty declaration must be accepted as well.

That's why you can call display() without defining it first.

printf() is similar. You will get a linker error if you forget -lc but from the compiler's point of view, the code is "good enough".

That will change as soon as you enable all warnings that your compiler has to offer and it will fail with an error when you disable K&C compatibility or enable strict ANSI checks.

Which is why "C" is often listed as "you shoot yourself into the foot" in "How to Shoot Yourself In the Foot Using Any Programming Language" kind of lists.

like image 43
Aaron Digulla Avatar answered Nov 07 '22 18:11

Aaron Digulla


it depends of your Cx (C89, C90, C99,...)

for function return values, prior to C99 it was explicitly specified that if no function declaration was visible the translator provided one. These implicit declarations defaulted to a return type of int

Justification from C Standard (6.2.5 page 506)

Prior to C90 there were no function prototypes. Developers expected to be able to interchange argu-ments that had signed and unsigned versions of the same integer type. Having to cast an argument, if the parameter type in the function definition had a different signedness, was seen as counter to C’s easy-going type-checking system and a little intrusive. The introduction of prototypes did not completely do away with the issue of interchangeability of arguments. The ellipsis notation specifies that nothing is known about the 1590 ellipsis supplies no information expected type of arguments. Similarly, for function return values, prior to C99 it was explicitly specified that if no function declaration was visible the translator provided one. These implicit declarations defaulted to a return type of int . If the actual function happened to return the type unsigned int , such a default declaration might have returned an unexpected result. A lot of developers had a casual attitude toward function declarations. The rest of us have to live with the consequences of the Committee not wanting to break all the source code they wrote. The interchangeability of function return values is now a moot point, because C99 requires that a function declaration be visible at the point of call (a default declaration is no longer provided)

like image 28
MOHAMED Avatar answered Nov 07 '22 19:11

MOHAMED


It probably does (assume such declaration as you wrote), but as you are not passing parameters, it just works fine. It's the same like if you declare int main() where it should actually be int main(int argc, char *argv[]).

So probably if you tried to pass some parameters (different from default ones) from main then use them in display it would fail.

BTW, for me it compiles, but generates warning:

$ gcc z.c
z.c:8:6: warning: conflicting types for ‘display’ [enabled by default]
z.c:4:5: note: previous implicit declaration of ‘display’ was here
like image 38
kompas Avatar answered Nov 07 '22 18:11

kompas