Can we call functions before defining it? - c

#include <stdio.h>
void main()
{
m();
}
void m()
{
printf("hi");
}
Output
hi
Warnings
main.c:11:10: warning: conflicting types for 'm' [enabled by default]
void m()
^
main.c:7:9: note: previous implicit declaration of 'm' was here
m();
^
Why this program runs successfully even though m() is called before it is defined?
And what is the meaning of the warning?

C89 allow this by implicitly converting the return type of function and parameter passed to it to int. See here.
But, this is not valid in C99 and later. This has been omitted from the standard. Either you have to declare a prototype for your function or define it before main. See the result here. There is a compile time error in this case.

If you don't declare a function in K&RC/C89, it's implicitly declared as returning int. Since yours returns void there's a mismatch.
If you add a prototype:
void m(void);
...before it's called, it'll fix things.

No, but you can declare it:
#include <stdio.h>
// declare m()
void m();
void main()
{
// use m()
m();
}
// define m()
void m()
{
printf("hi");
}

function declaration needs to be add before the first call of the function.
A full declaration includes the return type and the number and type of the arguments. This is also called the function prototype.
So you are Missing function prototype.
Add function declaration as void m(); to the code.
Edit:
C program allow to use forward declaration
.
In your case void m(); represents forward declaration of a function and is the function's prototype. After processing this declaration, the compiler would allow the user to refer to the entity m in the rest of the program.
Definition for a function must be provided somewhere (same file or other, where it would be responsibility of the linker to correctly match references to particular function in one or several object files with its definition, which must be unique, in another): (From wikipedia page)
That is why defining function after main work in your program.

Yes - It is called using prototypes.
I.e. put
void m();
At the start of the file

No, you cant normally.
The code would print the error something like this if the function is not defined before invoking it:
s.c: In function 'main':
s.c:4:1: warning: implicit declaration of function 'm' [-Wimplicit-function-declaration]
4 | m();
| ^
s.c: At top level:
s.c:8:6: warning: conflicting types for 'm'
8 | void m(){
| ^
s.c:4:1: note: previous implicit declaration of 'm' was here
4 | m();
| ^
So, it is always a good practice to declare method before or inside of main method especially if you are defining a method outside the scope of main function.
The code snippet for best practice has been provided below:
#include <stdio.h>
void m();
void main()
{
m();
}
void m()
{
printf("hi");
}

Related

Why does the compiler not recognize the function void message()?

I am actually working C language on Ubuntu 18.04. I don't use any IDE.
#include <stdio.h>
void main()
{
message();
printf("\nCry, and you stop the monotomy!\n");
}
void message()
{
printf("\nSmile, and the worldsmiles with you...");
}
When I run this it returns error message as follows.
msg.c: In function ‘main’:
msg.c:5:2: warning: implicit declaration of function ‘message’ [-Wimplicit-function-declaration]
message();
^~~~~~~
msg.c: At top level:
msg.c:8:6: warning: conflicting types for ‘message’
void message()
^~~~~~~
msg.c:5:2: note: previous implicit declaration of ‘message’ was here
message();
^~~~~~~
When I put the message function above main() then it shows no error. Why is it? Can't we put functions after main()? What is implicit declaration here?
You can put functions after main if you want; just if you're calling them in main, before they're defined, you should also declare them before main:
void message();
void main()
...
Without this the compiler assumes that message is an externally linked function returning int, and then when it comes across your actual definition of message it complains about conflicting types for message (since it already decided that message returns int, not void).
You first to define or declare your method, before calling it. In the following example, I declare the method before calling it in main:
#include<stdio.h>
// Declare the method
void message();
void main()
{
// Call the method
message();
printf("\nCry, and you stop the monotomy!\n");
}
// Define the method
void message()
{
printf("\nSmile, and the worldsmiles with you...");
}
PS: I would change the return type of main() to an int. Read more in What should main() return in C and C++?
When the compiler gets to message(); (in main) the compiler knows nothing about the function message.
It now tries its best. So it gives you are warning and then assumes that message should have been declared int message();
So when the compiler finally gets to void message() - it says "hello - I thought it would be int messgae". Hence the warning.
Simply put either message before main, so when it gets to compiling main the compiler knows about message.
Or as other posters have said. Declare it at the top.
When i put the message function above main() then it shows no error. Why is it? Can't we put functions after main()?
C source files are parsed top-down. So by the time compiler sees the function call message (in main), it must know about it (the same applies to any symbol, basically). That's why putting it above works but below results in diagnostics.
At a minimum, you must provide a declaration for any identifier before their use.
What is implicit declaration here?
When the compiler sees a function call and didn't know about it, it assumes the function returns an int (Such as int message();). This is the "implicit declaration". This was an ancient rule that was valid until C99.
But in C99 and later, this rule has been removed. Thus your code (that puts the definition of "message" below main without a declaration) is invalid in C99 and later.
See C function calls: Understanding the "implicit int" rule.
Later when the compiler sees the actual definition of message (i.e., void message() {...), it sees the return type is actually void. Thus this conflicts with its own declaration (where it assumed its int). So it generates:
msg.c:8:6: warning: conflicting types for ‘message’

use of out-of-scope declaration

Code:
void foo() {
extern int a;
extern void b(int);
}
void bar() {
b(9); // ok, warning: use of out-of-scope declaration of 'b'
a=9; // error: use of undeclared identifier 'a'
}
Why the compiler doesn't just give a warning like use of out-of-scope declaration of 'a'?
This is because of the vestigial feature of implicit declaration of functions. If you had just
void bar()
{
b(9);
}
that would actually be 100% valid pre-standard C (well, except that void didn't exist back then, but that's not important right now) equivalent to writing
void bar()
{
extern int b();
b(9);
}
(Remember that an empty parameter list in a function declaration does not mean that the function takes zero arguments. It means the function takes an unspecified number of arguments.)
Now, when you have
void foo()
{
extern void b(int);
}
void bar()
{
b(9);
}
the implicit declaration means it's like you wrote
void foo()
{
extern void b(int);
}
void bar()
{
extern int b();
b(9);
}
The two declarations of the external symbol b are not compatible. If they were both visible in the scope of bar, this would be a constraint violation ("X is a constraint violation" is the closest the C standard ever comes to saying "a program that does X is invalid and the compiler must reject it"). But they're not, so instead, the program's meaning is undefined. clang seems to have decided to apply the declaration from the foo scope but also warn you about it, which seems fair to me. gcc does treat it as an error:
test.c:6:5: error: incompatible implicit declaration of function ‘b’
b(9);
^
test.c:2:17: note: previous implicit declaration of ‘b’ was here
extern void b(int);
^
("previous implicit declaration" is not quite right, but that is also not important right now.)
You can probably see how this sort of thing could lead to hard-to-find bugs, which is why modern best practice is to declare stuff with external linkage only at file scope, and to declare all functions with full prototypes.
Only functions are ever implicitly declared, which is why a gave a hard error; in your original example, a is completely invisible to bar. (Note that if you had redeclared it with a different type, that would also make the program's meaning undefined.)

Passing entire Array as a parameter into a function

I am trying to pass an entire array into a my function, but I am getting currently getting the error:
test.c: In function 'main':
test.c:4:18: error: expected expression before ']' token
method(myArray[]);
^
test.c: At top level:
test.c:8:6: warning: conflicting types for 'method' [enabled by default]
void method(int arr[]){
^
test.c:4:3: note: previous implicit declaration of 'method' was here
method(myArray[]);
^
test.c: In function 'method':
test.c:9:3: warning: incompatible implicit declaration of built-in function 'printf' [enabled by default]
printf("DATA: %d",arr[2]);
^
This is my code (a simplified version of what I'm trying to do that throws up the same error:
int main(){
int myArray[3];
myArray[2]=12;
method(myArray[]);
}
void method(int arr[]){
printf("DATA: %d",arr[2]);
}
When passing an array to a function, you don't need the [] after it. Just using the name of the array is sufficient.
Also, you need to either define or declare your functions before they're used, and you need to #include <stdio.h> so the compiler knows the definition of printf.
#include <stdio.h>
void method(int arr[]);
int main(){
int myArray[3];
myArray[2]=12;
method(myArray);
}
void method(int arr[]){
printf("DATA: %d",arr[2]);
}
More than one point to be mentioned here,
Firstly, include the required header files which contains the function signature of the library functions you're going to use.
Secondly, either forward declare the function prototype or define the function before usage. Be aware, the ancient implicit declaration rule has been officially dropped from the C standards.
Thirdly, change
method(myArray[]);
to
method(myArray);
as the array name itself gives you the base address of the array, which is basically what you need to pass.

What does void function in C return?

#include <stdio.h>
void main()
{
int k = m();
printf("%d", k);
}
void m()
{
printf("hello");
}
Output
hello5
What is the void function returning here?
If there is no printf() then the output is 1.
What is happening here?
A void function does not return anything. Your program invokes undefined behavior because it implicitly defines m to have return type int (in C89, if a function is called before it is declared, it's implicitly assumed to have return type int), but then defines it with return type void.
If you add a forward-declaration for m, the compiler will correctly complain that you're trying to use the return value of a void function, which is not possible.
In both cases (void m with caller expecting int, void main with caller-in-C-library expecting int), this is undefined behavior, and your compiler should have chewed you out, e.g. [GCC 4.8 with -Wall]:
test.c:3:6: warning: return type of ‘main’ is not ‘int’
void main()
^
test.c: In function ‘main’:
test.c:7:5: warning: implicit declaration of function ‘m’
int k = m();
^
test.c: At top level:
test.c:13:6: warning: conflicting types for ‘m’
void m()
^
test.c:7:13: note: previous implicit declaration of ‘m’ was here
int k = m();
^
"Implicit declarations" exist only for backward compatibility with pre-C1989 programs, which are more than 20 years out of date at this point. If you had written this code in a more modern style you would've gotten a hard error:
#include <stdio.h>
extern void m(void);
int main(void)
{
int k = m();
printf("%d", k);
return 0;
}
void m(void)
{
printf("hello");
}
⇒
test.c: In function ‘main’:
test.c:7:13: error: void value not ignored as it ought to be
int k = m();
^
The key addition is the extern void m(void); line. The compiler isn't allowed to look ahead to the definition of m when it checks main for errors, so you need a forward declaration to tell it what m's type really is. You should also know that in C (but not C++), void m() means "m takes an unspecified number of arguments". To declare a function taking no arguments, which is what you wanted, you have to write void m(void).
I believe what is happening on your specific system is that the return value of printf, which your code officially ignores, is being left in the return-value register and thus interpreted as the return value of m, but you cannot rely on anything predictable happening. That is what 'undefined behavior' means.
This is undefined behavior.
The reason the compiler lets you do the assignment is that there is no prototype of m available to it. When this happens, C standard says that the function must return int. Since in this case the actual function return type is void, the behavior is undefined. The value that you get in variable k is entirely arbitrary.
The return value of a function usually stored in the one of the CPU registers, EAX for x86. As C it just a friendly assembler, you can always read the value from the register. And you will get whatever was there. Efficiently, int k = m() tells program to store value of register EAX in the variable k.
You have not declared void m(); before calling it in main.
Some compilers assume the return type of unknown function symbols as int (unknown at the time of compilation of course) . In fact, your compiler has probably issued a compilation warning on this.
If you declare this function before main (where it should be declared), then you will probably get a compilation error.

In my code, why is lack of a function declaration a non-issue for one function, but throws a warning for another?

In the following program,I use two functions prd() and display().I have declared neither of them ahead of main() before invoking them in main(),and I have defined both after main().Yet while prd() works smoothly inside main(),invoking display() shows the warning " previous implicit declaration of 'display' was here ".What is different about display() that there is a warning for it but not for the other funciton prd()?I have declared neither of them to begin with.Still there is warning due to invocation of one, but other one works fine.
#include<stdio.h>
int main()
{
int x=8,y=11;
printf("The product of %d & %d is %d",x,y,prd(x,y));
display();
return 0;
}
int prd(int x,int y)
{
return x*y;
}
void display()
{
printf("\n Good Morning");
}
PS: And I would really appreciate if you can answer this secondary question --"Is function declaration not necessary at all in C provided there is a definition for it?".I have the habit of declaring all functions of the program before the main() function, and then defining them after the main() function.Am I wrong?
When you use undeclared display() the compiler implicitly declares it as if it were returning int.
When the compiler finally sees the definition of display(), it sees that the return type is void, but it's already assumed it be int and so the definition and the implicit declaration differ, hence the error/warning.
The error occurs because C considers all non-initiated functions with a return type of int. Your display function is later defined with void return type.
Changing the return type of display() to int removes the warning.
By default, compiler assumes non-declared functions as returning int.
This is true for your prd function, but it does not match with display() as its void. This causes compiler to raise a warning.
For 2nd, its always appropriate to declare functions.

Resources