vaib <va************@gmail.comwrites:
It really seems that C never ceases to amaze . All this time
i've been doing C and i thought i was quite adept at it but i was
wrong . So without wasting any more time , here's the confusion .
I read in K&R that ANSI introduced the concept of function
prototyping in C and it was missing there initially ( it borrowed the
concept from C++ ) _but_ it did it make it compulsory to actually
include the function declaration in the program , the reason being -
so that older C code ( the ones missing the declarations ) could
run on newer compilers too . So the situation now is this - if there
is no function declaration corresponding to the function call and the
call does not say anything about the return type then the compiler
should assume a declaration with an int return type .
For certain values of "now".
In the C89/C90 standard, which K&R2 describes, the situation is
basically what you've described. In the C99 standard, the "implicit
int" rule has been dropped, so the examples you show are illegal (more
precisely, they're constraint violations requiring diagnostics).
for example ,
main()
{ fun(3) ;
return 0 ;
}
Please use a more traditional code layout, even for short examples
like this.
main()
{
fun(3);
return 0;
}
In C90, the compiler will assume that fun is a function returning int
with a single parameter of type int (the latter because that's what
you passed it).
in this case the compiler assumes this declaration - int fun( the
standard says nothing about the parameters so thats implementation
dependent ) ;
No, it's not implementation dependent; the compiler's assumption about
the parameter types is based on the actual types of the arguments you
pass, after promotion. (For example, short is promoted to int and
float to double, so if you pass a float argument it will assume the
parameter is of type double.)
and the code compiles without any hitch .
Right -- but if you use C99 mode you'll at least get a warning.
You'll also probably get a warning on the declaration of main; use
"int main(void)" rather than "main()".
my question is what sort of declaration would the
compiler assume in the following case :
main()
{
void * p ;
p = fun(3) ;
}
in the above case the return type is mentioned as void * .
main()
{
void *p;
p = fun(3);
}
A C90 compiler will assume that fun takes one argument of type int and
returns a result of type int. In the absence of a visible
declaration, it *always* assumes a return type of int. There is no
implicit conversion from int to void*, so you should get at least a
warning even in C90 mode.
also what happens in this case :
main()
{
void * p ;
p = malloc(sizeof(int)) ;
return 0 ;
}
the above code also compiles and _executes_ successfully on
gcc .
main()
{
void *p;
p = malloc(sizeof(int));
return 0;
}
sizeof yields a result of type size_t, which is an alias (a typedef)
for some predefined unsigned integer type. Since sizeof is an
operator, not a function, the compiler knows this.
Let's assume size_t is unsigned long in the current implementation.
Then a C90 compiler will assume that malloc takes an argument of type
unsigned long (possibly declared as size_t, but that doesn't matter
for these purposes) and returns a result of type int. You then
attempt to assign this int result to an object of type void*, which is
a constraint violation requiring a diagnostic. gcc doesn't complain
about this by default, because with no options specified gcc is not a
conforming C90 compiler. Try invoking it with at least "-ansi
-pedantic", and possibly "-Wall -Wextra" in addition, and you'll get
at least one warning.
The best lesson to learn from this is not how compilers behave when
you write bad code like this, but how to write good code that the
compiler won't complain about. If you use a standard function,
*always* provide a #include directive for the appropriate header. If
you call your own function, *always* provide a prototype for it, not
just an old-style declaration, but a prototype that specifies the
types of the parameters. And if the compiler complains about a type
mismatch, adding a cast is almost never the right solution; more
often, it's like taping over a warning light on your car's dashboard.
few more regarding these concepts have cropped up lately in my mind
but i'll ask them as the thread proceeds .
--
Keith Thompson (The_Other_Keith)
ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"