I have a question regarding to the function declaration:
I declared a function in b.c
//b.c
void getNumber();
//common header
common.h
In a.c I use it like this:
//a.c
#include "common.h"
void getInfo()
{
getNumber();
}
but it complain the getNumber is implicit declaration of function, what is the reason?
add the following line to common.h
void getNumber();
the b.c file should contain the function definition in this way
void getNumber() {
....
}
You need to declare or define your function first before using it.
If your declaration void getNumber(); was read by the compiler after its first use (void getInfo()), you would get the warning warning: implicit declaration of function ‘getNumber’. This happened because the compiler, when first encountering getNumber in void getInfo() had to guess its return type - hence the warning. I think this is what you are doing even though your example code does not show it that way.
If your void getNumber(); was read by the compiler first, no warning would occur.
Putting your function declaration in a header file like is a good idea. Be sure to include "common.h" first before your getInfo().
Related
Came across a situation where I was in doubt how to define the prototype the correct way. It´s easier to just look at a simple example:
Document A.c:
#define foo bar
void mon() {
foo();
}
Document B.c:
void bar() {
Do something;
}
Gives following warning:
Warning: Function does not have a full prototype
Normally I would solve it by:
extern void foo(void);
But as example show, the function dont exactly exist but is defined to point on another function. What is the correct way to make a prototype for this?
If the compiler encounters the declaration extern void foo(void); after the #define foo bar for the same source file, it will parse it as extern void bar(void); And the linker will just solve the bar symbol.
Note that you definition of bar is not consistent with the declaration above. The definition of bar should read:
void bar(void) {
// Do something;
}
in C, unlike C++, an argument list of (void) is subtly different from an empty argument list.
I think, that what happens is the following:
The compiler replaces the macro foo with bar but since at that stage bar is not declared anywhere as a function the compiler will complain, that it cannot find it.
Please see more: Are prototypes required for all functions in C89, C90 or C99?
Here is my original function (test.c):
#include <stdlib.h>
int main()
{
void *p = malloc(1);
free(p);
return 0;
}
If I re-define malloc in gcc cmd line with -D, gcc compiles it fine. (why it doesn't complain at my_malloc()?)
gcc -c -Wall -D malloc=my_malloc test.c
If I change the malloc name in my code to malloc2:
#include <stdlib.h>
int main()
{
void *p = malloc2(1);
free(p);
return 0;
}
And then re-define it, gcc now finally complains:
$ gcc -c -Wall -D malloc2=my_malloc test.c
test.c: In function ‘main’:
test.c:5:5: warning: implicit declaration of function ‘my_malloc’ [-Wimplicit-function-declaration]
void *p = malloc2(1);
Could someone help me explain why this is happening?
This has to do with how the preprocessor is working.
Assuming you #include <stdlib.h> at the top of your file, the first thing that happens is that this include file is basically imported into your source file. Next, the define passed in to the command line gets processed.
In the first case, this changes not only the call to malloc in your code but also the declaration of malloc imported from stdlib.h. So no implicit declaration. In the second case, the malloc2 call gets changed, but there's no corresponding declaration that gets swapped out as well. So you get the warning.
This is under gcc 4.1.2.
The warning you get in the third case is because you have used a function malloc2() (or my_malloc() in case you use the -Dmalloc2=my_malloc define) without a prototype. In this case, the <stdlib.h> defined prototype doesn't match the define you make in the command line, and you don't get a prototype for it anymore.
As standard behaviour, if you don't include a prototype for a function before it's first use, it defaults to return int and to use an undefined number of parameters. This means that the compiler is assuming you have a int my_malloc(); function defined elsewhere and as you are trying to assign an integer value to a pointer variable, there's something wrong in your code.
If you want the compiler assume your malloc implementation is like the standard library one, just define it with void *malloc(const size_t); before that first use.
#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");
}
In a particular C project, a file say file1.c uses a function say FUNCTION2(). The FUNCTION2() is declared in file2.c. An extern declaration of FUNCTION2() is there in file1.h
The file1.c adds only file1.h.
In file1.h, the file2.c/file2.h is not added. Still the compilation is successful and the functionality is working.
In the compilation list of the project, file2.c/file2.h is compiled first. But is that possible to call functions without adding the header file?
You can, but I wouldn't advise it. You have arranged things to force the compiler to exploit implicit declaration:
int main()
{
foo(2); /* The compiler emits this by implicit declaration. */
return 0;
}
int foo(int x)
{
return x;
}
In your explicit case, extern is telling the compiler to expect foo to come from a different compilation unit.
The standard thing to do would be to put a prototype of foo in a header and include that.
I'm programming in C and my gcc compiler gives me the following warning in my function call in mySedondFile.c:
implicit declaration of function 'func'
The function prototype is declared in myfile.h as:
void func(char*);
Function definition is in myfile.c
void func(char*x);
mySecondFile.c contains:
#include "myfile.h"
func("Hello");
I'm missing why this would complain.
That error is emitted because func has not been declared at the point at which you call it.
It sounds like your header files aren't quite as you describe. Perhaps there is some conditional code. Maybe you have a header guard that is not working right. Another possibility is that you have got a letter case error and declared the function Func but called it with func. Very hard to say without seeing the actual files but you need to look for a reason why func is not declared in the mySecondFile.c translation unit.
To illustrate this a little more clearly, the following code:
int main(void)
{
func("Hello");
return 0;
}
results in this warning:
prog.c: In function ‘main’:
prog.c:3: warning: implicit declaration of function ‘func’
which is exactly as you report.
According to your description, your code includes a header file which declares func. The compiler begs to differ with you and it remains for you to work out why func is not declared.