why is casting malloc a bad thing?

E

E. Robert Tisdale

Chris said:
Someone notes that, if one follows the "comp.lang.c accepted
practice" of not casting malloc() return values, and uses most
ordinary C89/C90 compilers in their default non-warning modes
so that one gets only the required diagnostics, forgetting to


For example, if one were to write:

struct zorg *new_zorg(double degree_of_evilness) {
struct zorg *new = malloc(sizeof *new);

new->degree = degree_of_evilness;
return new;
}

and feed it to the Generic C Compiler, one might get:

% cc -c zorg.c
zorg.c: In function `new_zorg':
zorg.c:4: warning: initialization makes pointer from integer without a cast

The problem is that you are using an inferior C compiler
or that you have forgotten the appropriate options:

> cc -Wall -c zorg.c
zorg.c: In function `new_zorg':
zorg.c:6: warning: implicit declaration of function `malloc'
zorg.c:6: warning: initialization makes pointer from integer \
without a cast

This provides an *explicit* warning
of the implicit declaration of function `malloc'.
It is certainly true that this warning leaves something to be
desired. The problem is not making a "pointer from integer",
but rather with "malloc never explicitly declared, thus implicitly
declared instead". Nonetheless, this is hardly a *new* problem:

% cc -c oops.c
oops.c:6: syntax error before `for'
% cat oops.c
/* kind of like strlen() but returns an int *./
int like_strlen(const char *p) {
int i;

/* we just need to find the first p that is '\0' */
for (i = 0; p != 0; i++)
continue;
return i;
}

There is nothing wrong on line 6, nor line 5, nor 4 (blank), nor
3, nor even line 2 -- the problem is all the way back on line 1,
where a typographic error inserted a period between the * and /
meant to close the comment. There are all kinds of constructs like
this, where a compiler issues the wrong message. Programmers *need*
to learn not to trust where the machine points, in the same way
that automobile mechanics need to learn not to assume that, if the
On Board Diagnostics in an engine computer says "oxygen sensor
failure", it is not necessarily the sensor itself that failed.
(The problem can be in the wire connecting the sensor to the
computer. The sensor is a "replacement item" -- the ones in the
exhaust system in particular may have only a few years' lifetime
-- so the diagnostic is *usually* right, but not always.)

It is always a good idea to compare the machine's complaint against
what you (believe you) know to be the case. If the machine says
"you are making a pointer from an integer", but you know malloc()
does not return an integer, then you should ask yourself: where is
this integer? Why does the compiler believe there is an integer
here? Then, if all else fails, you could even post to comp.lang.c:

"I have this C code here, and the compiler is giving me a
message involving an `integer' when there is no integer.
Why is that?"

Ideally, you should include a complete, compilable chunk of code,
and the exact text of the error or warning message, too. But the
goal here -- besides fixing the problem -- is learning why a C
compiler might think there is an integer here, when you are certain
there is none. Then you will hear all about "implicit int function
declarations", why they are bad, that your compiler needs a tuneup
(e.g., "-Wmissing-declarations") if not a complete replacement,
and of course the inevitable cascade of "don't cast malloc in C /
compile your C code with an Ada-I-mean-C++-compiler" flamage. :)


I know that you worked a long time on this
but it is a fallacious argument.

http://www.don-lindsay-archive.org/skeptic/arguments.html

Your first example shows that you are using an inferior C compiler
or that you didn't know about the option that would give you
and explicit diagnostic of the true problem
or that you knew about the option and suppressed it:

Argument By Half Truth (Suppressed Evidence)

Your second example is a straw man and a bad analogy
because, unlike the first example, the compiler cannot recognize it
as an *acceptable* C program.
It probably isn't reasonable to expect a C compiler
to parse comments and diagnose typographical errors.
You can't compile your second example, but the first example:
> expand zorg.c
#include<stdio.h>

struct zorg {
double degree;
};

struct zorg *new_zorg(double degree_of_evilness) {
struct zorg *new = malloc(sizeof *new);
new->degree = degree_of_evilness;
return new;
}

int main(int argc, char* argv[]) {
struct zorg* p = new_zorg(666.0);
fprintf(stdout, "%f = p->degree\n", p->degree);
free(p);
return 0;
}

compiles:
> cc -Wall -std=c99 -pedantic -o zorg zorg.c
zorg.c: In function `new_zorg':
zorg.c:8: warning: implicit declaration of function `malloc'
zorg.c:8: warning: initialization makes pointer from integer \
without a cast
zorg.c: In function `main':
zorg.c:16: warning: implicit declaration of function `free'

and links and runs:
666.000000 = p->degree

just fine on my system.
 
C

CBFalconer

E. Robert Tisdale said:
Chris Torek wrote:
.... snip ...

The problem is that you are using an inferior C compiler
or that you have forgotten the appropriate options:
.... snip ...

I know that you worked a long time on this
but it is a fallacious argument.

Chris, I trust you are making suitable notes. Has anyone got a
decent Ascii Art version of 'His Masters Voice'. The ineffable
joy of sitting at the feet of the master!
 
C

Christian Bau

"E. Robert Tisdale said:
CBFalconer wrote:

http://cbfalconer.home.att.net

Hi Chuck,

I found your resume:

http://cbfalconer.home.att.net/cbf/cbfres03.htm

It says:

Education: McGill University, Honors Mathematics and Physics.

But it doesn't say when you graduated or what degree(s) you got.
It doesn't mention any formal training in computer science?
Did you retire after consulting for Otis Elevator in 2001?
Or have you simply neglected to update your resume?

I think we have found ourselves a nice little stalker here?
 
M

MSG

Christian Bau said:
I think we have found ourselves a nice little stalker here?

No, I think Mr. Tisdale is recruiting for NASA. They need a Canadian
for their one-way Mars mission.
 
C

Chris Torek

[editing partly by me, partly by CBFalconer]
Chris said:
[by omitting a needless cast, on] the Generic C Compiler, one might get:
zorg.c: In function `new_zorg':
zorg.c:4: warning: initialization makes pointer from integer without a cast

(which is not a very *good* diagnostic, but is at least a diagnostic.)

Chris, I trust you are making suitable notes. Has anyone got a
decent Ascii Art version of 'His Masters Voice'. The ineffable
joy of sitting at the feet of the master!

Actually, he is not even a particularly good troll, in this case.
Note the attempt to specify the amount of time I "worked" on the
above (it is wrong; had I taken more time, I could have written a
much shorter article, to paraphrase Blaise Pascal). Old Usenet
hands should spot this sort of thing from miles away. :)

More on topic, however (the only reason for a followup), ERT *does*
have a point, if not very well expressed.

Earlier, someone (I have forgotten who) quoted the old adage, "it
is a poor workman who blames his tools" -- and it is true that a
*good* workman can make do even with klunky or "inferior" tools,
such as the Generic C Compiler (which does not *have* "the appropriate
options" -- the error message's resemblance to another compiler's,
one that does have such an option, is sheer coincidence). But it
is also true that a good workman -- or "workperson", or perhaps
even "workunit" if we wish to be non-animist as well as nonsexist
:) -- with good tools can do a better, faster, more thorough,
less-frustrating, and/or less-tiring job than the same entity with
the poor tools.

If Mr Tisdale simply said that he has neither sympathy nor empathy
for anyone stuck with a low-quality compiler, or even that he
personally refuses to use any compiler that lacks a "warn on use
of unprototyped function" diagnostic, I would have no argument.
Indeed, I encourage those with poor tools to obtain better ones.
At the same time, however, I acknowledge that these lower-quality
tools exist and are used every day; and I argue that "not casting
malloc" is the "belt-and-suspenders" approach, if you will, to
avoiding one particular common error. If one is sure of the quality
of one's suspenders, one should feel free to go about belt-less.

As another example, I myself refuse to limit my own code to six
monocase characters in external identifiers. I find this quite
constraining, and none of the systems I have dealt with in the last
15 to 20 years have had this limit -- though I did use a few that
had 7 or 8 characters, dual-case, in the mid-1980s. But while I
choose to do this, I do not tell others that they *should*. This
is one of thousands of tradeoffs one must make every day. The
trick when making such tradeoffs is comparing costs and benefits,
and "spending" the least for the most benefit. Some even choose
to spend effort compiling what they claim to be C code with C++
compilers -- which of course makes it C++ code instead, unless they
expend quite a lot more effort to avoid the various pitfalls that
can occur here. Presumably they find some benefit that I do not.

In short (perhaps too late for that, unless I were to work a long
time on this article), good tools are a good thing -- but if you
can easily write your code so that even the not-so-good tools catch
errors, you should consider doing so. In this case, the cost is
low, perhaps even zero or negative, and the benefit varies from
none (in the "good tools" case) to significant.
 
S

Severian

Chris, I trust you are making suitable notes. Has anyone got a
decent Ascii Art version of 'His Masters Voice'. The ineffable
joy of sitting at the feet of the master!

WWKKWWWWWWKKWWWWWWKKWWWWWWKKWWKKWWWWKKWWWWKKWWWWWWWWKKWWWWKKWWWWWWWWWW
WWWWWWKKWWWWWWKKWWWWWWKKWWWWWWWWWWWWWWWWWWWWWWKKWWWWWWWWWWWWWWKKWWKKWW
WWKKWWWWKKWWWWWWWWKKWWWWWWWW.. WWWW WWWWWWKKWWKKWWKKWWWWWWWWWW
WWWWWWWWWWWWKKWWWWWWWWWW WWWWWWWWWWWWWWKKWWWWKK
WWKKWWKKWWWWWWWWKKWWWW WWWWKKWWKKWWWWWWWWWW
WWWWWWWWWWKKWWWWWW WWWWWWWWWWKKWWKKWW
WWKKWWKKWWWWKKWW WWWWKKWWWWWWWWWW
WWWWWWWWWWWWWW.. ,,::::.. WWWWWWWWKKWWWW
WWKKWWWWKKWWWW ,,iittttii,,::.. WWWWKKWWWWWWKK
WWWWWWWWWWKK ,,;;;;iittii;;,,,,,,:: ..,, WWWWKKWWWWWW
WWKKWWKKWWWW .. ::;;;;,,;;,,,,,,,,::.. :::: WWWWWWWWKKWW
WWWWWWWWWWWW ,,;;,,,,,,,,,,,,,,:: ,,.. ..KKWWWWWWWW
WWKKWWKKWW ..,,;;;;,,,,,,,,,,,,::.. ..,,,, ..WWKKWWKKWW
WWWWWWWWWW ::;;;;ii;;,,,,::,,::::::.. ::::;; WWWWWWWWWW
WWKKWWWWWW ..iiiiii;;,,,,,,::,,::,,::,,,,;;;;.. WWKKWWKKWW
WWWWWWKK ..;;iiiiii;;;;,,;;,,,,,,;;iiiiii;;.. WWWWWWWWWW
WWKKWWWW ,,;;iiiiii;;;;,,,,,,,,,,;;iiiiiiii.. WWWWKKWWWW
WWWWWWWW ::iiiiiiiiii;;;;;;,,,,,,;;;;;;;;ttii,, WWWWWWKK
WWKKWWKK ..;;;;iittLLGGttttttiiiiiiiittjjttiiiiii.. WWKKWWWW
WWWWWWWW ..;;;;iiffLLDDEEEEDDffttLLEEKKKKEELLfftt::.. WWWWWWWW
WWKKWWWW ..;;iittjjffffDDEEGGjjiiDDKKDDGGDDDDffjj;; WWKKWWWW
WWWWWWKKWW ..::;;;;iijjGGEEEEEEGGjj;;LLEEEEEEEEEELLjjii:: WWWWWWKK
WWKKWWWWWW ..,,;;;;iittiitttttttttt;;ffGGffffLLtt,,tttt:: WWWWKKWWWW
WWWWWWKKWWWW,,,,;;;;;;iiiiiiiiiitttt,,;;LLtttttt,,;;ttLL,,WWKKWWWWWWWW
WWKKWWWWWWKKii,,;;ii;;;;,,;;,,iiii;;;;,,jjjjii;;;;;;ttGG::WWWWWWWWKKWW
WWWWWWKKWWWWttiiiiii;;;;;;;;ttLLffttjjLLGGDDffiiiittttLL WWKKWWWWWWWW
WWKKWWWWWWWWiiii;;;;;;ii;;ttGGLLEEEEEEKKKKDDLLjjffffffff..WWWWWWKKWWWW
WWWWWWKKWWWWjjtt;;iiiiiittLLGGffLLLLDDEEDDDDGGLLffLLGGGG;;WWKKWWWWKKWW
WWKKWWWWKKWW;;iiiiiiiiiiffDDDDLLLLLLGGGGDDEEEEGGffGGGGGGttWWWWWWWWWWWW
WWWWWWWWWWWW,,iiiiiittttffDDEEDDEEEEGGEEKKKKEEffLLDDDDDDffKKWWKKWWKKWW
WWKKWWKKWW,,,,iittiiiittffGGttttttffLLGGGGGGLLjjLLDDEEEEttWWWWWWWWWWWW
WWWWWWWWiiiiiijjjjjjttffffffjjttjjGGGGGGLLGGLLGGDDDDEEEE;;WWWWKKWWKKWW
WWKKWWfftt;;LLjjffLLffffLLLLjjiittttjjLLffLLDDEEEEEEEEff;;iiWWWWWWWWWW
WWWWWW;;..ttEEttffLLGGGGLLLLffjjttttjjffLLDDEEKKKKKKKKLL,,ttttWWKKWWWW
WWWW::..,,ffEEffjjLLLLLLGGDDGGLLffLLLLLLDDEEKKKKKKEEKKDD,,::;;;;WWWWii
;;....;;ffLLEEDDttffLLGGLLLLGGEEEEEEEEKKKKKKKKEEKKEEEEEEii;;..,,,,;;tt
.....::jjGGGGDDEEffjjffLLLLffffffGGEEEEEEEEEEKKEEKKEEKKEEfftt;;::..::tt
...::;;jjDDDDGGEEGGiijjffGGffLLLLLLGGGGDDEEKKEEKKEEKKKKDDLLjjtt;;::::..
,,,,iiiiEEDDDDDDDDttttffLLLLLLGGLLGGDDEEEEEEKKEEDDKKEEDDffjjLLGGtt,,..
,,;;ttffDDEEDDDDEELLttjjLLLLLLGGLLDDEEEEEEEEEEDDDDKKDDLLffGGEEEEtt,,::
,,;;iiGGGGEEKKEEEEDDjjttffffLLLLDDGGDDDDEEGGDDDDEEGGLLjjDDEEKKLLii,,,,
;;iiiiLLEEDDEEEEDDDDffffffjjffLLGGGGDDGGLLGGGGDDLLGGLLEEEEKKGGjjii;;;;
iiiittttLLEEEEEEKKKKjjttffffjjffffffjjffffLLDD;;GGKKKKKKEEDDffttii;;;;
iiiiiittffLLGGDDEEKKDDffffffjjjjttttiittffjjiittKKKKEEEEGGLLttiiii;;;;
iiiittiiffffjjffjjLLDDEEDDLLttjjjjjjttjjttffKKKKDDGGGGLLLLttttiiii;;;;
iiiiiittttjjffjjffffffLLDDEEEELLffffjjttDDKKKKDDGGGGffffffttiiii;;;;ii
iiiiiittttttjjjjjjjjffffffLLLLGGDDffffEEEEDDGGGGLLLLffjjttiiii;;iiiiii
 
R

Richard Bos

E. Robert Tisdale said:
Why should C programmers cobble their code
just to accommodate inferior C compilers?

Then again, why should C programmers cobble their code just to
accomodate inferior C++ compilers?

Richard
 
M

MSG

Severian said:
WWKKWWWWWWKKWWWWWWKKWWWWWWKKWWKKWWWWKKWWWWKKWWWWWWWWKKWWWWKKWWWWWWWWWW
WWWWWWKKWWWWWWKKWWWWWWKKWWWWWWWWWWWWWWWWWWWWWWKKWWWWWWWWWWWWWWKKWWKKWW
WWKKWWWWKKWWWWWWWWKKWWWWWWWW.. WWWW WWWWWWKKWWKKWWKKWWWWWWWWWW
WWWWWWWWWWWWKKWWWWWWWWWW WWWWWWWWWWWWWWKKWWWWKK
WWKKWWKKWWWWWWWWKKWWWW WWWWKKWWKKWWWWWWWWWW
WWWWWWWWWWKKWWWWWW WWWWWWWWWWKKWWKKWW
WWKKWWKKWWWWKKWW WWWWKKWWWWWWWWWW
WWWWWWWWWWWWWW.. ,,::::.. WWWWWWWWKKWWWW
WWKKWWWWKKWWWW ,,iittttii,,::.. WWWWKKWWWWWWKK
WWWWWWWWWWKK ,,;;;;iittii;;,,,,,,:: ..,, WWWWKKWWWWWW
WWKKWWKKWWWW .. ::;;;;,,;;,,,,,,,,::.. :::: WWWWWWWWKKWW
WWWWWWWWWWWW ,,;;,,,,,,,,,,,,,,:: ,,.. ..KKWWWWWWWW
WWKKWWKKWW ..,,;;;;,,,,,,,,,,,,::.. ..,,,, ..WWKKWWKKWW
WWWWWWWWWW ::;;;;ii;;,,,,::,,::::::.. ::::;; WWWWWWWWWW
WWKKWWWWWW ..iiiiii;;,,,,,,::,,::,,::,,,,;;;;.. WWKKWWKKWW
WWWWWWKK ..;;iiiiii;;;;,,;;,,,,,,;;iiiiii;;.. WWWWWWWWWW
WWKKWWWW ,,;;iiiiii;;;;,,,,,,,,,,;;iiiiiiii.. WWWWKKWWWW
WWWWWWWW ::iiiiiiiiii;;;;;;,,,,,,;;;;;;;;ttii,, WWWWWWKK
WWKKWWKK ..;;;;iittLLGGttttttiiiiiiiittjjttiiiiii.. WWKKWWWW
WWWWWWWW ..;;;;iiffLLDDEEEEDDffttLLEEKKKKEELLfftt::.. WWWWWWWW
WWKKWWWW ..;;iittjjffffDDEEGGjjiiDDKKDDGGDDDDffjj;; WWKKWWWW
WWWWWWKKWW ..::;;;;iijjGGEEEEEEGGjj;;LLEEEEEEEEEELLjjii:: WWWWWWKK
WWKKWWWWWW ..,,;;;;iittiitttttttttt;;ffGGffffLLtt,,tttt:: WWWWKKWWWW
WWWWWWKKWWWW,,,,;;;;;;iiiiiiiiiitttt,,;;LLtttttt,,;;ttLL,,WWKKWWWWWWWW
WWKKWWWWWWKKii,,;;ii;;;;,,;;,,iiii;;;;,,jjjjii;;;;;;ttGG::WWWWWWWWKKWW
WWWWWWKKWWWWttiiiiii;;;;;;;;ttLLffttjjLLGGDDffiiiittttLL WWKKWWWWWWWW
WWKKWWWWWWWWiiii;;;;;;ii;;ttGGLLEEEEEEKKKKDDLLjjffffffff..WWWWWWKKWWWW
WWWWWWKKWWWWjjtt;;iiiiiittLLGGffLLLLDDEEDDDDGGLLffLLGGGG;;WWKKWWWWKKWW
WWKKWWWWKKWW;;iiiiiiiiiiffDDDDLLLLLLGGGGDDEEEEGGffGGGGGGttWWWWWWWWWWWW
WWWWWWWWWWWW,,iiiiiittttffDDEEDDEEEEGGEEKKKKEEffLLDDDDDDffKKWWKKWWKKWW
WWKKWWKKWW,,,,iittiiiittffGGttttttffLLGGGGGGLLjjLLDDEEEEttWWWWWWWWWWWW
WWWWWWWWiiiiiijjjjjjttffffffjjttjjGGGGGGLLGGLLGGDDDDEEEE;;WWWWKKWWKKWW
WWKKWWfftt;;LLjjffLLffffLLLLjjiittttjjLLffLLDDEEEEEEEEff;;iiWWWWWWWWWW
WWWWWW;;..ttEEttffLLGGGGLLLLffjjttttjjffLLDDEEKKKKKKKKLL,,ttttWWKKWWWW
WWWW::..,,ffEEffjjLLLLLLGGDDGGLLffLLLLLLDDEEKKKKKKEEKKDD,,::;;;;WWWWii
;;....;;ffLLEEDDttffLLGGLLLLGGEEEEEEEEKKKKKKKKEEKKEEEEEEii;;..,,,,;;tt
....::jjGGGGDDEEffjjffLLLLffffffGGEEEEEEEEEEKKEEKKEEKKEEfftt;;::..::tt
..::;;jjDDDDGGEEGGiijjffGGffLLLLLLGGGGDDEEKKEEKKEEKKKKDDLLjjtt;;::::..
,,,,iiiiEEDDDDDDDDttttffLLLLLLGGLLGGDDEEEEEEKKEEDDKKEEDDffjjLLGGtt,,..
,,;;ttffDDEEDDDDEELLttjjLLLLLLGGLLDDEEEEEEEEEEDDDDKKDDLLffGGEEEEtt,,::
,,;;iiGGGGEEKKEEEEDDjjttffffLLLLDDGGDDDDEEGGDDDDEEGGLLjjDDEEKKLLii,,,,
;;iiiiLLEEDDEEEEDDDDffffffjjffLLGGGGDDGGLLGGGGDDLLGGLLEEEEKKGGjjii;;;;
iiiittttLLEEEEEEKKKKjjttffffjjffffffjjffffLLDD;;GGKKKKKKEEDDffttii;;;;
iiiiiittffLLGGDDEEKKDDffffffjjjjttttiittffjjiittKKKKEEEEGGLLttiiii;;;;
iiiittiiffffjjffjjLLDDEEDDLLttjjjjjjttjjttffKKKKDDGGGGLLLLttttiiii;;;;
iiiiiittttjjffjjffffffLLDDEEEELLffffjjttDDKKKKDDGGGGffffffttiiii;;;;ii
iiiiiittttttjjjjjjjjffffffLLLLGGDDffffEEEEDDGGGGLLLLffjjttiiii;;iiiiii


Nice sig!
 
D

Dave Thompson

On 26 Jan 2004 18:50:46 -0800, (e-mail address removed) (Paul Hsieh) wrote:
No, its a language weakness issue. One of the few good things to come
out of the C99 spec is the adoption of C++'s requirement for
prototype, and not assuming the default: int ()(int) . <snip>

C99 does not require prototype forms. It does (changed from C90)
require that functions be *declared* before use; that declaration may
be either prototype or old-style/K&R1; the former is preferable, but
not required. In C90 if you did not declare a function, it was
implicitly int ()() -- unspecified args, not one (of type) int.
- David.Thompson1 at worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top