malloc warning gcc > 4.0

malloc warning gcc > 4.0

Post by mark » Fri, 21 Oct 2005 03:01:33


Hi All,


When I compile this code:

int main() {
char* p;
p = (char*)malloc(10*sizeof(char));
return(0);
}

with gcc 4.0.1, I get the warning:
warning: incompatible implicit declaration of built-in function 'malloc'

What is wrong? I know it works with gcc 3.3.6.

Thanks,
Mark
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

malloc warning gcc > 4.0

Post by Martin Amb » Fri, 21 Oct 2005 15:53:11


What's wrong
1) is that you neither followed the newsgroup nor checked its FAQ before
posting. That is grossly impolite. (And telling you so usually triggers
some ignorant responses accusing me of being impolite. Go figure.)
2) is that you have no declaration for malloc in scope. Fix that with
#include <stdlib.h>
Of lesser importance
3) You are casting the return value from malloc, a bad idea.
4) You are pointlessly using sizeof(char) which is 1 by definition.
Fixing 3 & 4 is easy. Here are two fixes
p = malloc(10 * sizeof *p); /* if the type of *p might change */
p = malloc(10); /* if *p is always going to be char */
5) You are not checking to see if malloc() succeeded.
6) You are not freeing the allocated space.
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.

 
 
 

malloc warning gcc > 4.0

Post by Keith Thom » Fri, 21 Oct 2005 15:53:19

ark < XXXX@XXXXX.COM > writes:

gcc 3.3.6 has a flaw, in that it failed to give you the warning. gcc
4.0.1 corrects the flaw. (It's not a flaw in the sense of violating
the language; the warning isn't required, but it's useful.)

Your error is in failing to add the line "#include <stdlib.h>" to the
top of your program. Without this directive, which brings in a
correct declaration of malloc(), the compiler assumes that malloc()
returns int rather than void*. gcc 4.0.1 happens to know that the
predefined malloc() returns void*, and is able to give you the
warning. (Presumably it wouldn't be able to issue the warning for a
function that's not predefined.)

That's not the only problem with your code.

"int main()" is acceptable, but "int main(void)" is better because
it's more explicit.

As a matter of style, "char *p;" is better than "char* p;" (though of
course the compiler doesn't care). C's declaration syntax needs to be
read from the inside out. The declaration
char *p;
in effect says that *p is of type char, so p is of type char*. This
matters if you declare multiple variables in a single declaration:
char *p, q;
declares p as a pointer to char, and q as a char. If you join the '*'
to the type name:
char* p, q;
it looks like p and q are both of type char*.

In "p = (char*)malloc(10*sizeof(char));", the cast is unnecessary and
ill-advised. malloc() returns a result of type void*, which can be
implicitly converted to any object pointer type. The cast hides the
failure to include <stdlib.h> (as you saw with gcc 3.3.6). In effect,
the cast tells the compiler, "Shut up, I know what I'm doing" -- even
if you don't.

sizeof(char) is by definition 1. So the line can be changed to
p = malloc(10);
or, if you might change the type of p later:
p = malloc(10 * sizeof *p);
In the latter case, we apply sizeof to *p rather than to the type so
we don't have to change the line if the type of p changes. (Don't
worry about dereferencing an uninitialized pointer here; the argument
to sizeof isn't evaluated unless it's a variable-length array.) Once
you get used to the idiom, it's more obvious at a glance that it's
correct. With sizeof(char), or sizeof(some_type), you have to go back
to the declaration of p to be sure you have the right type. With
p = malloc(10 * sizeof *p);
you're saying "Allocate an array of 10 of whatever type p points to",
which is exactly what you want.

In a real program, you'd want to check the result of malloc() and take
some action (possibly aborting the program) if it failed. You'd also
want to call free() to release the allocated memory. In a toy program
like this, that's not as important.

Finally, in
return(0);
the parentheses are unnecessary. The syntax of a return statement is
return <expression>;
A parenthesized expression is allowed, of course. The problem is that
it makes the return statement look like a function call. It's not
a function call, and it shouldn't look like one.

We don't often see a program that provides so much opportunity for
commentary in so few lines. Was it deliberate?

--
Keith Thompson (The_Other_Keith) XXXX@XXXXX.COM <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
--
comp.lang.c.moderated - moderation
 
 
 

malloc warning gcc > 4.0

Post by Alan Balme » Fri, 21 Oct 2005 15:53:38


Exactly what it says. You have not provided an explicit declaration of
malloc, which is in stdlib.h, and this particular compiler knows what
it should be.

Then, eliminate the cast in the malloc statement, which is not needed,
make the main definition compliant, note that sizeof(char) is
guaranteed to be 1, and you'll have

#include <stdlib.h>

int main(void) {
char* p;
p = malloc(10);
return(0);
}

which should compile without error.

In a real program, you shouldn't forget to free p when you're done
with it.
--
Al Balmer
Balmer Consulting
XXXX@XXXXX.COM
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

malloc warning gcc > 4.0

Post by Flash Gord » Fri, 21 Oct 2005 15:54:01


No, it does not work perfectly, it fails silently. I'll bet that on gcc
3.3.6 you had a warning until you added the cast.

If there is no declaration in scope for a function C assumes it returns
an int, obviously malloc does *not* return an int, and gcc 4.0.1 is
obviously smart enough to realise that this is a problem for malloc. The
solution is to provide at least a declaration or, better yet, a
prototype, and the best way to do that is always to include the correct
header. A corrected version follows:

#include <stdlib.h> /* which declares all sorts of stuff including
malloc and free */

int main(void) /* tell the compiler it takes no parameters */
{
char *p;
p = malloc(10); /* sizeof char is 1 by *definition* */
free(p);
p = malloc(10 * sizeof *p); /* useful for when p is not obviously a
char */
free(p);
return 0; /* return is not a function so the parenthesis are not
required */
}
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

malloc warning gcc > 4.0

Post by Willer » Fri, 21 Oct 2005 15:54:11


Your code is wrong. Working code is not necessarily correct code (and
vice versa).

You haven't #included <stdlib.h>. Therefore malloc() is implicitly
assumed to return an int. You're then casting this int to a char * so
you can assign it to p. This is an exceptionally bad idea because it
will blow up on any platform where sizeof(int)<sizeof(char *) (which is
basically any serious platform these days).

Every coding standards doc I've seen says "Do not cast the return value
of any function", which removes the possibility of this kind of bug.

HTH.
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

malloc warning gcc > 4.0

Post by Kalle Olav » Fri, 21 Oct 2005 15:58:41

mark < XXXX@XXXXX.COM > writes:


Your program calls malloc without declaring it, so GCC assumes
malloc returns an int. However GCC also knows that malloc should
return a pointer (that furthermore is different from all other
pointers if it's not NULL, and this enables some optimizations).
Because of this mismatch, you get the warning. To fix it,
#include <stdlib.h>.


Even with that version, it's likely to fail on machines where
sizeof(int) != sizeof(void*).
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

malloc warning gcc > 4.0

Post by Tim Woodal » Fri, 21 Oct 2005 16:01:02

On Wed, 19 Oct 2005 18:01:33 -0000,


That's the compiler telling you your code is buggy (and always has
been)

Drop the cast and you would have got a warning with gcc 3.3.6 as well.
(so that cast is bad because it's stopped you being alerted to a bug)

#include <stdlib.h> to get a prototype for malloc. Currently your
implicit prototype has a return type of int.


Also sizeof(char) is always 1 so this is slightly redundant. If you want
the sizeof in there then sizeof *p would be preferable.


in summary:

#include <stdlib.h>

int main(void) {
char* p;
p = malloc(10); /* or p = malloc(10 * sizeof *p); */
free(p); /* OK so the OS will probably do this for you anyway */
return 0;
}


Tim.


--
God said, "div D = rho, div B = 0, curl E = - @B/@t, curl H = J + @D/@t,"
and there was light.

http://www.yqcomputer.com/ ://www.locofungus.btinternet.co.uk/
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

malloc warning gcc > 4.0

Post by Jack Klei » Fri, 21 Oct 2005 16:01:08

On Wed, 19 Oct 2005 18:01:33 -0000, mark < XXXX@XXXXX.COM > wrote in
comp.lang.c.moderated:


Add this and try compiling it again:

#include <stdlib.h>


You shouldn't be casting the return value of malloc() in C. Why are
you using the cast? I bet it is because you get a compiler error if
you don't.


Yes, absolutely. "implicit declaration" means that you do not have a
prototype or declaration in scope. Under versions of the C language
standard (prior to 1999), the compiler automatically assumes the
function you are calling returns an int and pretty much takes whatever
arguments you pass to it. Since malloc() returns a pointer to void,
and not an int, the compiler complains if you try to assign the return
value to a pointer. So you add the cast to shut up to compiler.


What is wrong is that your program generates undefined behavior. You
are lying to your compiler. By not including a prototype for
malloc(), you are telling the compiler that malloc() returns an int.
But it does not.

On many platforms, where int and void* happen to be the same size, and
the compiler returns them from functions the same way, this undefined
behavior seems to "work", but it is still wrong. On some processors,
even if int and void* are the same size, they are returned in
different registers, address registers versus data registers, this
will always crash horribly.

And when you upgrade the operating system you are using from 32 bits
to 64 bits, this is almost guaranteed to fail.


Include <stdlib.h> so you have a proper prototype for malloc() in
scope, and remove the cast on the return value.

And no, this did not "work" with gcc 3.3.6. You created undefined
behavior and it just so happened that it did what you wanted to do.
That did not make it correct.

--
Jack Klein
Home: http://www.yqcomputer.com/
FAQs for
comp.lang.c http://www.yqcomputer.com/ ~scs/C-faq/top.html
comp.lang.c++ http://www.yqcomputer.com/ ++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.yqcomputer.com/ ~ajo/docs/FAQ-acllc.html
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

malloc warning gcc > 4.0

Post by Jonathan L » Fri, 21 Oct 2005 16:01:30


Under the older version, it didn't know that malloc() should be declared
as 'extern void *malloc(size_t);', but now it does. Because you did not
#include <stdlib.h>, it assumes that the declaration of malloc() is
'extern int malloc();', which is wrong. If you'd ever coded on an
Motorola 680x0 machine, you'd know that pointers were returned in
address registers and integers in the data registers, and mis-declaring
(or not declaring - amounts to the same thing) malloc() and friends was
a quick recipe for core dumps and other disasters. Another class of
machine I worked on had word-based addressing, and a different
representation for byte addresses. If you didn't declare malloc() to
return 'char *' (it pre-dated the 1989 standard by a few years), you got
an erroneous value into any pointer except a 'char *' and crashes
followed. You got quite good at ensuring malloc et al were properly
declared in that environment.

The older GCC will complain if you ask it to; -Wmissing-prototypes would
certainly do it; you might find -Wall is sufficient.

--
Jonathan Leffler #include <disclaimer.h>
Email: XXXX@XXXXX.COM , XXXX@XXXXX.COM
Guardian of DBD::Informix v2005.02 -- http://www.yqcomputer.com/
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

malloc warning gcc > 4.0

Post by Alan Balme » Wed, 26 Oct 2005 18:26:43

On Thu, 20 Oct 2005 06:53:38 -0000, Alan Balmer < XXXX@XXXXX.COM >




And, of course, check the return value of malloc to be sure it
succeeded.
--
Al Balmer
Balmer Consulting
XXXX@XXXXX.COM
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

malloc warning gcc > 4.0

Post by Peter Pich » Wed, 26 Oct 2005 18:27:30


void main () { printf("Hello, world!"); }

Better? ;-)
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

malloc warning gcc > 4.0

Post by Flash Gord » Wed, 26 Oct 2005 21:22:34


I'm sure you could get a few more problems if you tried
float main (double d) { printf("Hello! % %p %d",d); }
Admitedly it is no longer just a hello world program ;-)
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
 
 
 

malloc warning gcc > 4.0

Post by Brian Ingl » Fri, 04 Nov 2005 20:51:48

On Thu, 20 Oct 2005 07:01:30 -0000 in comp.lang.c.moderated, Jonathan






Adding -W in older versions and -Wextra in recent versions of GCC will
produce additional warnings which may be useful and informative about
the state of your code.

--
Thanks. Take care, Brian Inglis Calgary, Alberta, Canada

XXXX@XXXXX.COM (Brian[dot]Inglis{at}SystematicSW[dot]ab[dot]ca)
fake address use address above to reply
--
comp.lang.c.moderated - moderation address: XXXX@XXXXX.COM -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.