I have the following code created in Konsole
de CentOS7
where, as you can see, I try to create a process with the function/command fork()
and manage the different circumstances of using it:
#include <stdio.h>
#include <unistd.h>
void main(){
pid_t pid;
pid = fork();
if(pid == -1){
printf("Error al crear el proceso hijo\n");
exit(0);
}
if(pid){
printf("Proceso padre, el PID de mi hijo es %d\n", pid);
}else{
printf("Soy el hijo, ejecutando herramienta date\n");
execve("bin/date", NULL, NULL);
}
}
When executing gcc test_fork.c
in Konsole
de Linux CentOS
I get the following error:
[vapaternina@localhost ~]$ gcc test_fork.c
test_fork.c: En la función ‘main’:
test_fork.c:10:3: aviso: declaración implícita incompatible de la función interna ‘exit’ [activado por defecto]
exit(0);
^
Let's go by parts:
Implied statement
By default, if we don't declare a function but use it , the compiler assumes that the function has the following prototype :
Which is equivalent to:
internal functions
Some compilers perform optimizations on the code in a specific way: they have a kind of language extension available , similar to reserved words , which replace certain functions of the language itself. the error message
It's telling you just that: the compiler provides a function
exit( )
of its own. This way of acting facilitates the optimization of the code, since the compiler contemplates the use of certain additional reserved words with a specific behavior and generates a special code in those cases.Explanation
Now we know what the message means: the default prototype generated by the compiler (
int exit( )
) conflicts with the compiler's own extension. Since such extensions are usually compatible with the features of the language, the extension will have the prototypevoid exit( int )
. And both things are not the same , hence the warning .Solution
You have several options:
Declare a function yourself
exit( )
:Use the corresponding header file:
Disable the use of that particular compiler extension (in which case it will usually give you the warning
función sin definir
):-fno-builtin
: Disables all internal functions.-fno-builtin-exit
: Disableexit( )
as internal function.add
#include <stdlib.h>
to your source codeC does a "wonderful" thing (ironic way), and that is that if you call a function that was not previously declared, instead of giving an error, the declaration is invented for you. This "implicit" declaration (invented I would say) always uses as return type
int
(just because), and as types of the parameters those that you have put in the invocation.So, for example, if you find this invocation:
and that function was not previously declared, the declaration is invented:
And keep going. This may be right, or it may be wrong. If the function in question (which would normally be in an external library or object) does not respond to that prototype, you may have problems at runtime.
On the other hand, some of the functions of the C standard library are known to the compiler. Although these functions are not strictly part of the language but of its standard library,
gcc
somehow it comes standard with the knowledge of what the prototype of these functions is. Among themprintf()
,exit()
etc.Then he has done something bordering on schizophrenia :-) In your code there is the function
exit(0)
, and it turns out that this function has not been previously declared, so he invents the declaration for it:but then, since it turns out that he
gcc
"knew" that function should actually bevoid exit(int);
, he finds that the implicit statement he just made up doesn't match what he knew should be output, so he gives you this warning, whose meaning is now more evident:The solution is to explicitly declare what the prototype of
exit()
. That is precisely the mission of a#include <stdlib.h>
since within that file.h
are the prototypes of several typical functions of the standard library,exit()
among them.