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

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’

Related

Why does a function that returns int not need a prototype?

I tried this program on DevC++ that would call two different types of function, one returning int and one returning char. I'm confused why the int function doesn't need a prototype, while the char one and any other type of function does.
#include <stdio.h>
//int function1();
char function2() ;
int main (){
int X = function1() ;
char Y = function2() ;
printf("%d", X) ;
printf ("%c", Y) ;
return 0 ;
}
int function1(){
return 100 ;
}
char function2(){
return 'B' ;
}
The output:
100B
If I remove the prototype for the char function, it results in:
[Error] conflicting types for 'function2'
[Note] previous implicit declaration of 'function2' was here
In the old days of C any function that was not declared explicitely was supposed to return int type when you call it.
If the compiler then finds the function implementation and sees an int return type, everything is fine.
If the function returns anything else than int you get the error message as you saw with the second function.
This implicit int type declaration was removed from the standard with C99. Now you should at least get a warning from your compiler when you use a function without prototype.
If you did not get any diagnostic message for first funcion, you should turn up warning level in your compiler or switch to at least C99 mode instead of ancient versions.
Edit:
Empty parameter lists in funcion definitions is a deprecated feature as well.
You should not use it.
Always provide prototype for every function with return type and parameter list.
If a function is used before it is declared, the usage becomes an implicit declaration of the function. When a function f is implicitly defined, the definition given to it is int f(), i.e. a function which accepts an unspecified number of arguments and returns an int.
This implicit definition of a function matches the actual definition of function1 but not function2. So calling function1 this way gives no error but attempting to call function2 this way results in the implicit definition not matching the actual definition, giving an error.
This behavior goes back to pre-standardized versions of C where all objects (and a function's return type) had a default type of int if not declared. This was still present in the C89 standard but removed in the C99 standard, although some compilers such as gcc still support this obsolescent usage as an extension.
It's just an ancient relic from when C was first designed. It was actually removed as early as C99, but many compilers still support this type of declaration. But it's not recommended to use it.
I'm not sure if there were any real rationale behind it, but C was heavily inspired by the language B. And in B you did not have to specify the return type for functions. That actually made perfect sense, because there was only one type, word.
In the same way you did not have to specify the type of variables either. You only specified if it had automatic or static storage. And that's where the completely useless keyword auto in C comes from. It does not mean the same as in C++. It just means "not static".

C : Why passing arguments less then function defined, Only warning shows up (No any error and it can run normally )

this maybe is a special case. When i tracing a C code i saw warning . said
implicit declaration of function 'Wifi_Hosts_Sync_Func' [-Wimplicit-function-declaration]
i tried to eliminate it by using extern the function void *Wifi_Hosts_Sync_Func
but if i do this compiler shows Error : Wifi_Hosts_Sync_Func too few arguments.
my question is WHY this code can works?! & WHY program didn't crash or flash out on "run time".
defined function need 5 argument ,calling code only gives 4 .
this program can run normally and succeed end. any ideas?
// warning msg.
../../../../git/source/TR-181/ml/cosa_wifi_dml.c: In function 'WiFi_HostSyncThread':
../../../../git/source/TR-181/ml/cosa_wifi_dml.c:756:2: warning: implicit declaration of function 'Wifi_Hosts_Sync_Func' [-Wimplicit-function-declaration]
Wifi_Hosts_Sync_Func(NULL,0, NULL, 1);
^~~~~~~~~~~~~~~~~~~~
in cosa_wifi_dml.c
void *WiFi_HostSyncThread()
{
fprintf(stderr,"[TRACE] before Wifi_Hosts_Sync_Func()");
Wifi_Hosts_Sync_Func(NULL,0, NULL, 1);
fprintf(stderr,"[TRACE] after Wifi_Hosts_Sync_Func()");
}
in cosa_wifi_apis.c
void *Wifi_Hosts_Sync_Func(void *pt, int index, wifi_associated_dev_t *associated_dev, BOOL bCallForFullSync, BOOL bCallFromDisConnCB )
{
fprintf(stderr,"[TRACE] Wifi_Hosts_Sync_Func() Call in.\n");
...
...
}
From C89, Section 3.3.2.2:
If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier, and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if, in the innermost block containing the function call, the declaration extern int identifier(); appeared.
This was removed in C99 though because it's confusing at best and harmful at worst.
Note that unlike C++, C uses () in the definition to say that the function takes an unknown number of arguments (none would be (void)). Calling it with any number of arguments would work and just push all those arguments to the stack and it would be up to the function to make sense of them.
So, it just implicitly declared an external function with an unknown number of arguments, so it compiles - it's still incorrect though. And if it does work anyway then you just got lucky because the name still matched so the linker linked the real function and in the cdecl calling convention the caller clears up the stack, so the function would still run but see garbage (probably an unrelated local variable of the outer function) as 5th argument. Since it's a boolean value, all that happens is that it's interpreted as either true or false or randomly one of the two (but if it were, say, a pointer, it could wreak all kinds of havoc).
If you explicitly define the function, you get an error, because you (correctly) declared it with 5 arguments but you (incorrectly) call it with 4.
And this is why this "feature" was removed: It makes code appear to work that is actually broken, which leads to strange bugs and confusion later on.
Function which does not take any arguments has to be declared as
TYPE func(void) not TYPE func(). Never declare functions like this as it is some historical depreciated "feature"
Before you call any function you need to have the function prototype to let complier know what return type and parameters function has.
Your function also has to return a pointer.
void *Wifi_Hosts_Sync_Func(void *pt, int index, wifi_associated_dev_t *associated_dev, BOOL bCallForFullSync, BOOL bCallFromDisConnCB );
void *WiFi_HostSyncThread(void)
{
void *result;
fprintf(stderr,"[TRACE] before Wifi_Hosts_Sync_Func()");
result = Wifi_Hosts_Sync_Func(NULL,0, NULL, 1); // and now you will have the error here.
fprintf(stderr,"[TRACE] after Wifi_Hosts_Sync_Func()");
return result;
}

error: conflicting types for ‘six’ with gcc

Receiving error: conflicting types for ‘six’ when attempting to compile.
void main(){
const int k = 4;
six(&k);
}
float * six(const int *x)
{
float *p = malloc(sizeof(float));
*p = (float)*x;
return p;
}
Here is what is going on.
When the compiler does not encounter a prototype for a function before a call to it, it deduces the prototype from the call itself, and assumes the return type to be int. This is what it does in your example.
Later it finds the definition of the function, and it finds that the return type is actually float, which does not match with the prototype it has deduced earlier. Hence the error of conflicting types (instead of, say, missing prototype).
The solution is to, of course, provide a prototype for the function before a call to it is made.
You didn't declare six to the compiler before you called it, so the compiler was forced to guess what the signature of six is (typically, this is something like int func()). When it saw the actual declaration, it threw an error because the actual function declaration didn't match its implicit declaration.
You need to declare functions before they are used; place a declaration like
float *six(const int *x);
before main.
Solution to your problem
Just add the following declaration before main():
float *six(const int *x);
Or put your float *six(const int *x) definition before the main() function.
Why the compiler complain conflicting types
Since there is no declaration of your six() function before the compiler compile the main function, it will deduce the prototype from the function callsite, and will assume the return type to be int. And when it compiles your six() function, the compiler will find two function with the same name but different return type, so it complain the conflicting types error.
Thanks to Ziffusion's comment.
why to adjust your code in the above way
You should declare/define each of your element before use in C.
For your currently code, you need to declare your function type before the main function, so that the compiler knows what six() is when compile the main function.
Why there should be a declaration before use in C
For variables and other data types, since C is strong typed. When the variable is used, it need to be declared first, so that the compiler knows what type the variable is, and could do data type check.
For functions, since the C compiler compiles the code function by function, and will generate a function call statement in the assembly, so the compiler need to know the function parameter and return value data type, so that it could generated correct instructions to do parameter passing, and return value restoring. Normally, the compiler will compile the function in a source code file one by one from the start of the file to the end of the file, so you need to declare the function type before use it.

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.

warning: implicit declaration of function

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.

Resources