Function declaration not needed when compiling two C files [duplicate] - c

This question already has answers here:
Is implicit function declaration legal in C89?
(2 answers)
Implicit function declarations in C
(6 answers)
What is the default C -std standard version for the current GCC (especially on Ubuntu)?
(7 answers)
Closed 3 years ago.
I was trying to simultaneously compile the following C files
file1.c
#include<stdio.h>
int main()
{
foo();
return 0;
}
file2.c
#include<stdio.h>
void foo()
{
printf("Hello");
}
I compiled the two files using the following command in linux
gcc file1.c file2.c -o file
It compiled successfully without any warnings and on running it gave the output as 'Hello'
Shouldn't file1.c require a prototype like void foo(). Is there anything in the C standard regarding this ?

Before C99, C had a thing called implicit declaration that allowed you to do that.
If you didn't specify a declaration for foo and you called foo, it was implicitly declared as int foo();.
This, however, was removed from C99 and subsequent standards.

Related

Why still compile successfully and got a.out after warning: implicit declaration of function? [duplicate]

This question already has answers here:
Implicit function declarations and linkage
(4 answers)
Closed 2 years ago.
Is it necessary to declare a variable before using it if the compilation works anyway ?
/* hello-world.c */
#include <stdio.h>
int main(void) {
printf("Hello World!\n");
printf("1 + 2 is: %d\n", sum(1, 2));
return 0;
}
/* sum.c */
int sum(int a, int b) {
return a + b;
}
I compile these code with gcc hello-world.c sum.c and clang hello-world.c sum.c,
both got a warning: implicit declaration of function 'sum' but compiled the a.out.
Is there any case proving it's absolutely necessary to declare before using in C?
(edit: Here, i mean the function prototype, if there is any confusion)
"proving" with C is done by the C Standard, not by observation of compilers. Because the standard leaves a lot of things up to compiler discretion .
This program was valid in C89 but is not valid in C99 and later (in which undeclared identifiers cannot be used in expressions).
What the compiler chooses to do with non-compliant programs is up to that compiler, except that some violations (including this one) must result in a diagnostic being printed. Perhaps your compiler opts to print the diagnostic and then go on to behave like C89 .
The classical case is incompatible implicit declaration:
// a.c
int f()
{
return g();
}
// b.c
float g() { return 3.14; }
In this case, it is undefined behavior.

Behavior of extern keyword in C [duplicate]

This question already has an answer here:
Why extern int a ; initialization giving error locally but not globally? [duplicate]
(1 answer)
Closed 5 years ago.
I surprised when compiled following program on GCC compiler. It's successfully worked. Compiler gives only warning.
warning: 'i' initialized and declared 'extern' [enabled by default] extern int i = 10; ^
My code:
#include <stdio.h>
//Compiler version gcc 4.9
extern int i = 10;
int main()
{
printf("%d\n",i);
return 0;
}
Output:
10
Why doesn't give compiler error? Is it undefined behavior?
You should not put your main function body in a header, but rather in a .c-file. Vice versa, you should not put extern in a .c-file but only in a header. That is the difference between declaration and definition.
Extern means, make this variable known, but there is no memory to be reserved for it. The compiler now says: Ok, I know you want this variable to be used, but it is only promised to be there, not actually defined.
The compiler anyway does not know about other objects (other .c-files) that might define this variable. So it keeps it to the linker to actually try to gather all variables.
If the linker now does not find that variable elsewhere, it implicitly makes the variable local, but warns about the broken C-standard.

Why doesn't compiler complain the variable is redefined? [duplicate]

This question already has answers here:
About Tentative definition
(2 answers)
Why does redefining a static global variable give a compile-time error when redefining a global variable does not?
(1 answer)
Closed 6 years ago.
I create a simple test.c file:
#include <stdio.h>
int a;
int a = 100;
void printA(void)
{
printf("a is %d\n", a);
}
Compile it to generate object file:
$ gcc -c test.c
$
It is OK! But per my understanding, the variable a should be redefined, is it right?
A variable is local to block it is defined.Once code in block is executed variable goes out of scope.In your case firstly a is defined globally.In second case it is defined inside a function.Thus, to compiler both a is different in both cases not the same.

gcc compiles with no error with no return type (even using -Wall) [duplicate]

This question already has answers here:
What should main() return in C and C++?
(19 answers)
Closed 6 years ago.
I'm wondering why gcc doesn't display an error while compiling, even while using the -Wall option. Also tried the -std=c89 option.
Here's the code:
#include <stdio.h>
int main(void)
{
printf("hello, world\n");
}
Sorry if this post is a duplicate but couldn't find a case where this option is being used.
Thanks!
In C++ and C99 and later, hitting the end of main() without returning a value is equivalent to returning 0. In earlier versions of the C standard it's undefined behavior which the compiler isn't obliged to issue a diagnostic for, although in practice GCC's likely doing an implicit return 0; just as it would for C++ or C99 onwards.
See What should main() return in C and C++? for a lot more detail.

C grammar compound statement [duplicate]

This question already has answers here:
Why was mixing declarations and code forbidden up until C99?
(6 answers)
Closed 8 years ago.
I was looking at the C grammer on K&R and i found this:
compound-statement:
{ declaration-list opt statement-list opt }
declaration-list:
declaration
declaration-list declaration
statement-list:
statement
statement-list statement
Which means that we can't have declarations after statements. However i am doing this really often like:
#include <stdio.h>
int main()
{
printf("Lets use a new block");
{
int a=1;
printf("%d",a);
int b=3;
printf("%d",b);
}
return 0;
}
This code compiles with no warning and no errors. Am i not understanding the grammar correctly?
To get the error you want, pass these flags to gcc:
-std=c90 -pedantic-errors
GNU extensions, as well as more recent C standards, allow declarations after other statements in a scope.
You understand the grammar fine. However, C has advanced since the K&R days and now the grammar accepts interleaved declarations and statements.

Resources