Christian Christmann wrote:
Please leave in attribution lines, the bits that say who said what. It
makes it easier to follow the thread.
Actually this is my question.
An easy example:
int main()
{
func();
return 0;
}
void func()
{
int a = 10;
}
Of course, the compiler complains that it does not know the function
'func' in the 'mai' function since it's unknown to it at that
point of the compilation process.
So, when the author mentions on his website (I mentioned in my first
message) "the compiler actually dos not "know" the signature of
malloc()", I understand it in the way that malloc is not known to the
compiler at that specific point of program.
Or is it possible for a function to be known to the compiler without
a prototype? If so, could you give me a short example.
There are a couple of different issues here. What the standard mandates
that the compiler must do and what the compiler can do in addition to
what the standard mandates. Also, what the standard mandates is
different in the most commonly implemented version of the standard (C90)
to the current version of the standard (C99). In the following I'm
assuming C90 (the commonly implemented standard). I'm also not going to
go in to the details of all the steps of the compilation.
The compiler first processes all the pre-processor directives, such as
#include. This in effect produces one very long source file with
everything in it which is then passed to the actual C compiler. If a
call to a function occurs in the pre-processed C file before a
definition is encounters the C standard mandates that the compiler treat
it as a function returning an int and taking an unspecified number of
parameters.
Now on to bits compilers are allowed to do but the standard does not
mandate. The standard mandates that under some conditions the compiler
produce a diagnostic (typically reported as a warning or error), such as
reporting a syntax error. However, the standard also allows the compiler
to produce diagnostics for any other reason it chooses. So, although the
compiler is required to assume malloc returns an int if it has not yet
seen a declaration of it, it is also allowed to say, "ah, but I know
malloc actually returns a void* because that is what the standard malloc
function returns, so I'm going to be nice and tell the user that they
have got it wrong." Indeed, some compilers will actually do this even
though it is not required. So in that sense a compiler writer can choose
to make the compiler "know" more than the standard says it has to know
and produce more helpful messages as a result.
So, given the following example of a *bad* program:
int main(void)
{
int i = malloc(5);
return 0;
}
The compiler is not *required* to produce an diagnostics (errors or
warnings), since it is required to assume that malloc returns an int
because it has not seen a diagnostic. However, some compilers will tell
you that this disagrees which what it knows is the standard declaration
of malloc.
A more common example of the same problem is:
int main(void)
{
int *ptr = (int*)malloc(5);
return 0;
}
Again, the compiler is required to assume that malloc returns an int,
which we all know is wrong. The cast then tells the compiler to convert
that expected in in to a pointer. So again, the compiler is *not*
required to complain. However, as before, there are some compilers that
will be helpful and complain.
As a final example, given:
int main(void)
{
int *ptr = malloc(5);
return 0;
}
The compiler is required to assume that malloc returns an int. However,
the standard also requires a diagnostic on attempting to assign an int
directly to a pointer. So due to the lack of the cast and the required
assumed return type of malloc, the compiler is *required* to produce a
diagnostic. Often the diagnostic will be something like, "attempt to
assign integer to pointer without cast" which often leads people who
don't know any better to add in the cast changing it to the previous
example.
Since malloc does not return an int, not of the examples I've given are
required to "work" whether or not the compiler complains and there are
real modern systems (some modern 64 bit systems in certain common modes)
where it will *not* work.