Related
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’
I've just come across someone's C code that I'm confused as to why it is compiling. There are two points I don't understand.
The function prototype has no parameters compared to the actual function definition.
The parameter in the function definition does not have a type.
#include <stdio.h>
int func();
int func(param)
{
return param;
}
int main()
{
int bla = func(10);
printf("%d", bla);
}
Why does this work?
I have tested it in a couple of compilers, and it works fine.
All the other answers are correct, but just for completion
A function is declared in the following manner:
return-type function-name(parameter-list,...) { body... }
return-type is the variable type that the function returns. This can not be an array type or a function type. If not given, then int
is assumed.
function-name is the name of the function.
parameter-list is the list of parameters that the function takes separated by commas. If no parameters are given, then the function
does not take any and should be defined with an empty set of
parenthesis or with the keyword void. If no variable type is in front
of a variable in the paramater list, then int is assumed. Arrays and
functions are not passed to functions, but are automatically converted
to pointers. If the list is terminated with an ellipsis (,...), then
there is no set number of parameters. Note: the header stdarg.h can be
used to access arguments when using an ellipsis.
And again for the sake of completeness. From C11 specification 6:11:6 (page: 179)
The use of function declarators with empty parentheses (not
prototype-format parameter type declarators) is an obsolescent
feature.
In C func() means that you can pass any number of arguments. If you want no arguments then you have to declare as func(void). The type you're passing to your function, if not specified defaults to int.
int func(); is an obsolescent function declaration from the days when there was no C standard, i.e. the days of K&R C (before 1989, the year the first "ANSI C" standard was published).
Remember that there were no prototypes in K&R C and the keyword void was not yet invented. All you could do was to tell the compiler about the return type of a function. The empty parameter list in K&R C means "an unspecified but fixed" number of arguments. Fixed means that you must call the function with the same number of args each time (as opposed to a variadic function like printf, where the number and type can vary for each call).
Many compilers will diagnose this construct; in particular gcc -Wstrict-prototypes will tell you "function declaration isn't a prototype", which is spot on, because it looks like a prototype (especially if you are poisoned by C++!), but isn't. It's an old style K&R C return type declaration.
Rule of thumb: Never leave an empty parameter list declaration empty, use int func(void) to be specific.
This turns the K&R return type declaration into a proper C89 prototype. Compilers are happy, developers are happy, static checkers are happy. Those mislead by^W^Wfond of C++ may cringe, though, because they need to type extra characters when they try to exercise their foreign language skills :-)
The empty parameter list means "any arguments", so the definition isn't wrong.
The missing type is assumed to be int.
I would consider any build that passes this to be lacking in configured warning/error level though, there's no point in being this allowing for actual code.
It's K&R style function declaration and definition. From C99 Standard (ISO/IEC 9899:TC3)
Section 6.7.5.3 Function Declarators (including prototypes)
An identifier list declares only the identifiers of the parameters of the function. An empty
list in a function declarator that is part of a definition of that function specifies that the
function has no parameters. The empty list in a function declarator that is not part of a
definition of that function specifies that no information about the number or types of the
parameters is supplied. (If both function types are "old style", parameter types are not compared.)
Section 6.11.6 Function declarators
The use of function declarators with empty parentheses (not prototype-format parameter
type declarators) is an obsolescent feature.
Section 6.11.7 Function definitions
The use of function definitions with separate parameter identifier and declaration lists
(not prototype-format parameter type and identifier declarators) is an obsolescent feature.
Which the old style means K&R style
Example:
Declaration: int old_style();
Definition:
int old_style(a, b)
int a;
int b;
{
/* something to do */
}
C assumes int if no type is given on function return type and parameter list. Only for this rule following weird things are possible.
A function definition looks like this.
int func(int param) { /* body */}
If its a prototype you write
int func(int param);
In prototype you can only specify the type of parameters. Parameters' name is not mandatory. So
int func(int);
Also if you dont specify parameter type but name int is assumed as type.
int func(param);
If you go farther, following works too.
func();
Compiler assumes int func() when you write func(). But dont put func() inside a function body. That'll be a function call
As stated #Krishnabhadra, all previous responses from other users, have a correct interpretation, and I just want to make a more detailed analysis of some points.
In the Old-C as in ANSI-C the "untyped formal parameter", take the dimencion of your work register or instruction depth capability (shadow registers or instruction cumulative cycle), in an 8bit MPU, will be an int16, in a 16bit MPU and so will be an int16 an so on, in the case 64bit architectures may choose to compile options like: -m32.
Although it seems simpler implementation at high level,
For pass multiple parameters, the work of the programmer in the control dimencion data type step, becomes more demanding.
In other cases, for some microprocessors architectures, the ANSI compilers customized, leveraged some of this old features to optimize the use of the code, forcing the location of these "untyped formal parameters" to work within or outside the work register, today you get almost the same with the use of "volatile" and "register".
But it should be noted that the most modern compilers,
not make any distinction between the two types of parameters declaration.
Examples of a compilation with gcc under linux:
In any case the statement of the prototype locally is of no use, because there is no call without parameters reference to this prototype will be remiss.
If you use the system with "untyped formal parameter", for an external call, proceed to generate a declarative prototype data type.
Like this:
int myfunc(int param);
Regarding parameter type, there are already correct answers here but if you want to hear it from the compiler you can try adding some flags (flags are almost always a good idea anyways).
compiling your program using gcc foo.c -Wextra I get:
foo.c: In function ‘func’:
foo.c:5:5: warning: type of ‘param’ defaults to ‘int’ [-Wmissing-parameter-type]
strangely -Wextra doesn't catch this for clang (it doesn't recognize -Wmissing-parameter-type for some reason, maybe for historical ones mentioned above) but -pedantic does:
foo.c:5:10: warning: parameter 'param' was not declared,
defaulting to type 'int' [-pedantic]
int func(param)
^
1 warning generated.
And for prototype issue as said again above int func() refers to arbitrary parameters unless you exclicitly define it as int func(void) which would then give you the errors as expected:
foo.c: In function ‘func’:
foo.c:6:1: error: number of arguments doesn’t match prototype
foo.c:3:5: error: prototype declaration
foo.c: In function ‘main’:
foo.c:12:5: error: too many arguments to function ‘func’
foo.c:5:5: note: declared here
or in clang as:
foo.c:5:5: error: conflicting types for 'func'
int func(param)
^
foo.c:3:5: note: previous declaration is here
int func(void);
^
foo.c:12:20: error: too many arguments to function call, expected 0, have 1
int bla = func(10);
~~~~ ^~
foo.c:3:1: note: 'func' declared here
int func(void);
^
2 errors generated.
If the function declaration has no parameters i.e. empty then it is taking unspecified number of arguments. If you want to make it take no arguments then change it to:
int func(void);
This is why I typically advise people to compile their code with:
cc -Wmissing-variable-declarations -Wstrict-variable-declarations -Wold-style-definition
These flags enforce a couple of things:
-Wmissing-variable-declarations: It is impossible to declare a non-static function without getting a prototype first. This makes it more likely that a prototype in a header file matches with the actual definition. Alternatively, it enforces that you add the static keyword to functions that don't need to be visible publicly.
-Wstrict-variable-declarations: The prototype must properly list the arguments.
-Wold-style-definition: The function definition itself must also properly list the arguments.
These flags are also used by default in a lot of Open Source projects. For example, FreeBSD has these flags enabled when building with WARNS=6 in your Makefile.
In the old-style declarator,
the identifier list must be absent unless
the declarator is used in the head of a function definition
(Par.A.10.1). No information about the types of the parameters is
supplied by the declaration. For example, the declaration
int f(), *fpi(), (*pfi)();
declares a function f returning an integer, a function fpi returning a pointer to an integer, >and a pointer pfi to a function returning an integer. In none of these are the parameter types >specified; they are old-style.
In the new-style declaration
int strcpy(char *dest, const char *source), rand(void);
strcpy is a
function returning int, with two arguments, the first a character
pointer, and the second a pointer to constant characters
SOURCE:- K&R book
I hope it cleared your doubt..
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().
I've just come across someone's C code that I'm confused as to why it is compiling. There are two points I don't understand.
The function prototype has no parameters compared to the actual function definition.
The parameter in the function definition does not have a type.
#include <stdio.h>
int func();
int func(param)
{
return param;
}
int main()
{
int bla = func(10);
printf("%d", bla);
}
Why does this work?
I have tested it in a couple of compilers, and it works fine.
All the other answers are correct, but just for completion
A function is declared in the following manner:
return-type function-name(parameter-list,...) { body... }
return-type is the variable type that the function returns. This can not be an array type or a function type. If not given, then int
is assumed.
function-name is the name of the function.
parameter-list is the list of parameters that the function takes separated by commas. If no parameters are given, then the function
does not take any and should be defined with an empty set of
parenthesis or with the keyword void. If no variable type is in front
of a variable in the paramater list, then int is assumed. Arrays and
functions are not passed to functions, but are automatically converted
to pointers. If the list is terminated with an ellipsis (,...), then
there is no set number of parameters. Note: the header stdarg.h can be
used to access arguments when using an ellipsis.
And again for the sake of completeness. From C11 specification 6:11:6 (page: 179)
The use of function declarators with empty parentheses (not
prototype-format parameter type declarators) is an obsolescent
feature.
In C func() means that you can pass any number of arguments. If you want no arguments then you have to declare as func(void). The type you're passing to your function, if not specified defaults to int.
int func(); is an obsolescent function declaration from the days when there was no C standard, i.e. the days of K&R C (before 1989, the year the first "ANSI C" standard was published).
Remember that there were no prototypes in K&R C and the keyword void was not yet invented. All you could do was to tell the compiler about the return type of a function. The empty parameter list in K&R C means "an unspecified but fixed" number of arguments. Fixed means that you must call the function with the same number of args each time (as opposed to a variadic function like printf, where the number and type can vary for each call).
Many compilers will diagnose this construct; in particular gcc -Wstrict-prototypes will tell you "function declaration isn't a prototype", which is spot on, because it looks like a prototype (especially if you are poisoned by C++!), but isn't. It's an old style K&R C return type declaration.
Rule of thumb: Never leave an empty parameter list declaration empty, use int func(void) to be specific.
This turns the K&R return type declaration into a proper C89 prototype. Compilers are happy, developers are happy, static checkers are happy. Those mislead by^W^Wfond of C++ may cringe, though, because they need to type extra characters when they try to exercise their foreign language skills :-)
The empty parameter list means "any arguments", so the definition isn't wrong.
The missing type is assumed to be int.
I would consider any build that passes this to be lacking in configured warning/error level though, there's no point in being this allowing for actual code.
It's K&R style function declaration and definition. From C99 Standard (ISO/IEC 9899:TC3)
Section 6.7.5.3 Function Declarators (including prototypes)
An identifier list declares only the identifiers of the parameters of the function. An empty
list in a function declarator that is part of a definition of that function specifies that the
function has no parameters. The empty list in a function declarator that is not part of a
definition of that function specifies that no information about the number or types of the
parameters is supplied. (If both function types are "old style", parameter types are not compared.)
Section 6.11.6 Function declarators
The use of function declarators with empty parentheses (not prototype-format parameter
type declarators) is an obsolescent feature.
Section 6.11.7 Function definitions
The use of function definitions with separate parameter identifier and declaration lists
(not prototype-format parameter type and identifier declarators) is an obsolescent feature.
Which the old style means K&R style
Example:
Declaration: int old_style();
Definition:
int old_style(a, b)
int a;
int b;
{
/* something to do */
}
C assumes int if no type is given on function return type and parameter list. Only for this rule following weird things are possible.
A function definition looks like this.
int func(int param) { /* body */}
If its a prototype you write
int func(int param);
In prototype you can only specify the type of parameters. Parameters' name is not mandatory. So
int func(int);
Also if you dont specify parameter type but name int is assumed as type.
int func(param);
If you go farther, following works too.
func();
Compiler assumes int func() when you write func(). But dont put func() inside a function body. That'll be a function call
As stated #Krishnabhadra, all previous responses from other users, have a correct interpretation, and I just want to make a more detailed analysis of some points.
In the Old-C as in ANSI-C the "untyped formal parameter", take the dimencion of your work register or instruction depth capability (shadow registers or instruction cumulative cycle), in an 8bit MPU, will be an int16, in a 16bit MPU and so will be an int16 an so on, in the case 64bit architectures may choose to compile options like: -m32.
Although it seems simpler implementation at high level,
For pass multiple parameters, the work of the programmer in the control dimencion data type step, becomes more demanding.
In other cases, for some microprocessors architectures, the ANSI compilers customized, leveraged some of this old features to optimize the use of the code, forcing the location of these "untyped formal parameters" to work within or outside the work register, today you get almost the same with the use of "volatile" and "register".
But it should be noted that the most modern compilers,
not make any distinction between the two types of parameters declaration.
Examples of a compilation with gcc under linux:
In any case the statement of the prototype locally is of no use, because there is no call without parameters reference to this prototype will be remiss.
If you use the system with "untyped formal parameter", for an external call, proceed to generate a declarative prototype data type.
Like this:
int myfunc(int param);
Regarding parameter type, there are already correct answers here but if you want to hear it from the compiler you can try adding some flags (flags are almost always a good idea anyways).
compiling your program using gcc foo.c -Wextra I get:
foo.c: In function ‘func’:
foo.c:5:5: warning: type of ‘param’ defaults to ‘int’ [-Wmissing-parameter-type]
strangely -Wextra doesn't catch this for clang (it doesn't recognize -Wmissing-parameter-type for some reason, maybe for historical ones mentioned above) but -pedantic does:
foo.c:5:10: warning: parameter 'param' was not declared,
defaulting to type 'int' [-pedantic]
int func(param)
^
1 warning generated.
And for prototype issue as said again above int func() refers to arbitrary parameters unless you exclicitly define it as int func(void) which would then give you the errors as expected:
foo.c: In function ‘func’:
foo.c:6:1: error: number of arguments doesn’t match prototype
foo.c:3:5: error: prototype declaration
foo.c: In function ‘main’:
foo.c:12:5: error: too many arguments to function ‘func’
foo.c:5:5: note: declared here
or in clang as:
foo.c:5:5: error: conflicting types for 'func'
int func(param)
^
foo.c:3:5: note: previous declaration is here
int func(void);
^
foo.c:12:20: error: too many arguments to function call, expected 0, have 1
int bla = func(10);
~~~~ ^~
foo.c:3:1: note: 'func' declared here
int func(void);
^
2 errors generated.
If the function declaration has no parameters i.e. empty then it is taking unspecified number of arguments. If you want to make it take no arguments then change it to:
int func(void);
This is why I typically advise people to compile their code with:
cc -Wmissing-variable-declarations -Wstrict-variable-declarations -Wold-style-definition
These flags enforce a couple of things:
-Wmissing-variable-declarations: It is impossible to declare a non-static function without getting a prototype first. This makes it more likely that a prototype in a header file matches with the actual definition. Alternatively, it enforces that you add the static keyword to functions that don't need to be visible publicly.
-Wstrict-variable-declarations: The prototype must properly list the arguments.
-Wold-style-definition: The function definition itself must also properly list the arguments.
These flags are also used by default in a lot of Open Source projects. For example, FreeBSD has these flags enabled when building with WARNS=6 in your Makefile.
In the old-style declarator,
the identifier list must be absent unless
the declarator is used in the head of a function definition
(Par.A.10.1). No information about the types of the parameters is
supplied by the declaration. For example, the declaration
int f(), *fpi(), (*pfi)();
declares a function f returning an integer, a function fpi returning a pointer to an integer, >and a pointer pfi to a function returning an integer. In none of these are the parameter types >specified; they are old-style.
In the new-style declaration
int strcpy(char *dest, const char *source), rand(void);
strcpy is a
function returning int, with two arguments, the first a character
pointer, and the second a pointer to constant characters
SOURCE:- K&R book
I hope it cleared your doubt..
For this code:
int i=0; char **mainp;
for(i=0;i<2;++i)
{
mainp[i]=malloc(sizeof(char)*200);
if(!scanf("%[^#],#",mainp[i]))
break;
if(i<2)
scanf("%[^#],#",mainp[i]);
}
GCC emits the warnings:
warning: implicit declaration of function ‘scanf’
warning: incompatible implicit declaration of built-in function ‘scanf’
warning: ‘mainp’ may be used uninitialized in this function
And I get a segmentation fault at runtime
input:(P>Q),(Q>R),-R#-P
output:
(P>Q),(Q>R),-R
(empt slot)
i expected to give me
(P>Q),(Q>R),-R
-P //where should i fix in my code such that it gives me expected
//output
Problem #1:
warning: ‘mainp’ may be used uninitialized in this function
You need to allocate memory for the array of arrays first.
char **mainp = malloc(sizeof(char*)*2);
Problem #2:
warning: implicit declaration of function ‘scanf’
warning: incompatible implicit declaration of built-in function ‘scanf’
You need to include stdio.h at the top of your file:
#include <stdio.h>
Problem #3: (Not included in your compiling warnings)
Remember to free both the allocated array members and also the array of array address.
gcc expects this line at the beginning of your file:
#include <stdio.h>
and a declaration of mainp like this one:
char *mainp[2];
You shouldn't use functions without declaring them; you used scanf, but at no point in your code is scanf declared. Since it's a standard library function it's declared in one of the standard headers, stdio.h, so you just need to include it:
#include <stdio.h>
Brian's answer is good for the other part