473,320 Members | 1,846 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

(FAQ details:) malloc(), void * and casts


This topic is a FAQ. But I have read the faq and spent a couple of
hours browsing the group archives, and still have a few questions that
I hope you can answer.

My understanding is that recommended practice is to not cast the
return value from malloc(). The rationale for this is that 1) the
cast is not needed and 2) the cast may mask errors.

I assume that the reason the cast is not needed has to do with the
fact that the the pointer returned from malloc() is a void *, and not
a pointer to any other type. (Is that correct?)

If so, could you explain _why_ (and the details of why) casting the
void pointer is not necessary?
(For my naive eye, assigning a pointer of one type (void) to a pointer
of another type (e.g. int) does not seem quite "correct".)

I do have the spec (ISO 9899:1999) at my desk, but I am not familiar
enough with it to find the answer to this one. So references to the
spec, possibly along with some interpretation, would also be helpful.
With kind regards
Asbjørn Sæbø
Nov 13 '07 #1
35 2034
Asbjørn Sæbø wrote:
My understanding is that recommended practice is to not cast the
return value from malloc(). The rationale for this is that 1) the
cast is not needed and 2) the cast may mask errors.
That is so.
I assume that the reason the cast is not needed has to do with the
fact that the the pointer returned from malloc() is a void *, and not
a pointer to any other type. (Is that correct?)
Precisely.
If so, could you explain _why_ (and the details of why) casting the
void pointer is not necessary?
Because according to the standard, pointer to void can be converted to
and from any other object pointer type.
(For my naive eye, assigning a pointer of one type (void) to a pointer
of another type (e.g. int) does not seem quite "correct".)
It's (part of) what the standard intended void * to be used for, as I
understand it.
I do have the spec (ISO 9899:1999) at my desk, but I am not familiar
enough with it to find the answer to this one. So references to the
spec, possibly along with some interpretation, would also be helpful.
Section 6.3.2.3 is fairly clear, I think.
Nov 13 '07 #2
Mark Bluemel <ma**********@pobox.comwrites:
Asbjørn Sæbø wrote:

[Why it it not necessary to cast the return value from malloc() ]
If so, could you explain _why_ (and the details of why) casting the
void pointer is not necessary?

Because according to the standard, pointer to void can be converted to
and from any other object pointer type.
[...]
Section 6.3.2.3 is fairly clear, I think.
"A pointer to void may be converted to or from a pointer to any
incomplete or object type. [...]"

And this conversion is implicit? And it is "kosher" in every way, and
should not elicit any warnings ("diagnostics"?) from the compiler?

The reason I ask is that I have been told that at least the Lint we
use at work will object to assigning a void* to e.g. an int *.

Asbjørn
Nov 13 '07 #3
Asbjørn Sæbø <in*****@invalid.invalidwrites:
This topic is a FAQ. But I have read the faq and spent a couple of
hours browsing the group archives, and still have a few questions that
I hope you can answer.

My understanding is that recommended practice is to not cast the
return value from malloc(). The rationale for this is that 1) the
cast is not needed and 2) the cast may mask errors.

I assume that the reason the cast is not needed has to do with the
fact that the the pointer returned from malloc() is a void *, and not
a pointer to any other type. (Is that correct?)

If so, could you explain _why_ (and the details of why) casting the
void pointer is not necessary?
(For my naive eye, assigning a pointer of one type (void) to a pointer
of another type (e.g. int) does not seem quite "correct".)
It isn't. And so the C language does the conversion for you using an
implicit conversion. (I think thats the terminology...)

http://www.stanford.edu/~blp/writing...lloc-cast.html
http://www.cpax.org.uk/prg/writings/casting.php
>
I do have the spec (ISO 9899:1999) at my desk, but I am not familiar
enough with it to find the answer to this one. So references to the
spec, possibly along with some interpretation, would also be helpful.
With kind regards
Asbjørn Sæbø
Nov 13 '07 #4
Asbjørn Sæbø wrote:
Mark Bluemel <ma**********@pobox.comwrites:
>Asbjørn Sæbø wrote:

[Why it it not necessary to cast the return value from malloc() ]
>>If so, could you explain _why_ (and the details of why) casting the
void pointer is not necessary?
Because according to the standard, pointer to void can be converted to
and from any other object pointer type.
[...]
>Section 6.3.2.3 is fairly clear, I think.

"A pointer to void may be converted to or from a pointer to any
incomplete or object type. [...]"

And this conversion is implicit?
If by that you mean you can simply assign a void * to an int *, yes.
And it is "kosher" in every way, and
should not elicit any warnings ("diagnostics"?) from the compiler?
Compilers can choose to warn you about just about anything, I believe.

But such code is strictly compliant.
The reason I ask is that I have been told that at least the Lint we
use at work will object to assigning a void* to e.g. an int *.
Then that lint is broken, IMHO. In ISO C (C++ is different), the direct
assignment is, in your words, "kosher" and is to be preferred to
casting, as casting can hide errors.

I recently spent a significant amount of time chasing a such an error -
lack of a prototype meant that the compiler took the return result of a
function as "int" (32-bits), that was cast to "int *" (64-bits) and half
the pointer was missing. Naturally the program crashed.

Without the unnecessary cast, the error would have been picked up much
earlier.
Nov 13 '07 #5
In article <rg*************@ardbeg.nordicsemi.no>,
Asbjørn Sæbø <in*****@invalid.invalidwrote:
>If so, could you explain _why_ (and the details of why) casting the
void pointer is not necessary?
(For my naive eye, assigning a pointer of one type (void) to a pointer
of another type (e.g. int) does not seem quite "correct".)
The purpose of the void pointer type is to hold pointers that are
really of another type. There's nothing you do with a void pointer
itself except pass it around and convert it to other types.

Converting between other pointer types on the other hand is unusual,
something you want to think twice about. It's reasonable to have to
be explicit about it if that's what you really want to do.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Nov 13 '07 #6
In article <fh**********@aioe.org>,
Mark Bluemel <ma**********@pobox.comwrote:
>If so, could you explain _why_ (and the details of why) casting the
void pointer is not necessary?
>Because according to the standard, pointer to void can be converted to
and from any other object pointer type.
This isn't sufficient explanation. The same is true of character
pointer types, but you do need a cast there.
>(For my naive eye, assigning a pointer of one type (void) to a pointer
of another type (e.g. int) does not seem quite "correct".)
>It's (part of) what the standard intended void * to be used for, as I
understand it.
This is better. Converting to and from void * isn't just legal, it's
what you're meant to do.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Nov 13 '07 #7
Mark Bluemel <ma**********@pobox.comwrites:
Asbjørn Sæbø wrote:
[...]
>If so, could you explain _why_ (and the details of why) casting the
void pointer is not necessary?

Because according to the standard, pointer to void can be converted to
and from any other object pointer type.
[...]
Section 6.3.2.3 is fairly clear, I think.
Yes, but that just says which conversions are allowed (and what they
mean), not which ones can be done implicitly.

6.5.16.1p1 describes the constraints for simple assignment, one of
which is:

one operand is a pointer to an object or incomplete type and the
other is a pointer to a qualified or unqualified version of void,
and the type pointed to by the left has all the qualifiers of the
type pointed to by the right

and paragraph 2 says:

In simple assignment (=), the value of the right operand is
converted to the type of the assignment expression and replaces
the value stored in the object designated by the left operand.

This is what allows a conversion (in either direction) between void*
and another pointer type (other than a pointer-to-function type) to be
performed implicitly.

There are similar rules for initialization and argument passing.

<OT>C++ has different rules.</OT>

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 13 '07 #8
On Nov 13, 5:14 am, Asbjørn Sæbø <inva...@invalid.invalidwrote:
This topic is a FAQ. But I have read the faq and spent a couple of
hours browsing the group archives, and still have a few questions that
I hope you can answer.

My understanding is that recommended practice is to not cast the
return value from malloc(). The rationale for this is that 1) the
cast is not needed and 2) the cast may mask errors.
Right. As you can see 1) is not actually a rationale at all -- its
just a confirmation that it happens to be legal due to the original
design of C, and therefore possible. Its like recommending that you
eat a gallon of whip cream every day because its possible. And 2)
simply does not apply at all on modern compilers -- pretty much every
compiler I use will warn me if I fail to include <stdlib.hand yet
use malloc().

This "recommendation" does not have any further basis to it. It also
ignores the obvious counter argument that the cast is necessary to
make the same code compatible with C and C++ (a useful thing, that is
in common practice). Many C++ compilers have vastly superior warnings
and can commonly produce better code, so it very often pays to compile
your ANSI C code with a C++ compiler. C++ compilers, these days, are
better maintained than C compilers.
I assume that the reason the cast is not needed has to do with the
fact that the the pointer returned from malloc() is a void *, and not
a pointer to any other type. (Is that correct?)
Right. void * is automatically coercible to any data pointer type in
C. (It is not in C++, and requires explicit casting.)
If so, could you explain _why_ (and the details of why) casting the
void pointer is not necessary?
The standard happens to allow this. Its a legacy thing -- in the past
(before vendors supported the ANSI standard) some compilers used to
allow coercion of any pair of pointers.
(For my naive eye, assigning a pointer of one type (void) to a pointer
of another type (e.g. int) does not seem quite "correct".)
Well, one way or another the result starting from malloc is a void *
anyways. Casting it doesn't change the real result, it just forces
the compiler to copy pointers of one type into pointers of a different
type because that's just the way C is.

But, with very simple use of macros on top of malloc, its possible to
synchronize the size of what you are allocating with the type of what
you are allocating (arrays need some extra consideration) which allows
you to ignore ANSI C's "extra flexibility" and retain a type-safe
subset of the language without losing relevant functionality.
I do have the spec (ISO 9899:1999) at my desk, but I am not familiar
enough with it to find the answer to this one. So references to the
spec, possibly along with some interpretation, would also be helpful.
Just keep in mind that the C spec was written in the 80s for a
language designed in the 70s by hackers borrowing from other languages
who were just throwing it together on their way to designing UNIX. A
lot of the things in that spec are of a "historical" or "legacy"
nature.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/

Nov 14 '07 #9
Paul Hsieh wrote:
Asbjørn Sæbø <inva...@invalid.invalidwrote:
>This topic is a FAQ. But I have read the faq and spent a couple
of hours browsing the group archives, and still have a few
questions that I hope you can answer.

My understanding is that recommended practice is to not cast the
return value from malloc(). The rationale for this is that 1)
the cast is not needed and 2) the cast may mask errors.

Right. As you can see 1) is not actually a rationale at all --
its just a confirmation that it happens to be legal due to the
original design of C, and therefore possible. Its like
recommending that you eat a gallon of whip cream every day
because its possible. And 2) simply does not apply at all on
modern compilers -- pretty much every compiler I use will warn
me if I fail to include <stdlib.hand yet use malloc().
Just a quick reply to warn newbies that this Hsieh post is utter
nonsense. Compilers should not warn when a cast is present,
because the cast says "I know what I am doing, so shut up". Also,
C is not C++. The languages are different, have different rules,
and should be treated differently.

--
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>
Try the download section.
--
Posted via a free Usenet account from http://www.teranews.com

Nov 17 '07 #10
"Paul Hsieh" <we******@gmail.comha scritto nel messaggio
news:11**********************@v23g2000prn.googlegr oups.com...
And 2) simply does not apply at all on modern compilers -- pretty much
every compiler I use will warn me if I fail to include <stdlib.hand yet
use malloc().
Yes. In fact I've always wondered why some people continue to say that...
Many C++ compilers have vastly superior warnings
and can commonly produce better code, so it very often pays to compile
your ANSI C code with a C++ compiler. C++ compilers, these days, are
better maintained than C compilers.
Ok for the warnings but:

1) Can you give me one example of better code? That would be
interesting...

2) What do you mean by "mantained". Maybe that we have fewer C compilers
than C++ ones? If this is what you meant, I won't be too happy about
that
Just keep in mind that the C spec was written in the 80s for a
language designed in the 70s by hackers borrowing from other languages
who were just throwing it together on their way to designing UNIX. A
lot of the things in that spec are of a "historical" or "legacy"
nature.
Quite illuminating...

Nov 19 '07 #11
On Nov 13, 8:46 pm, Paul Hsieh <websn...@gmail.comwrote:
On Nov 13, 5:14 am, Asbjørn Sæbø <inva...@invalid.invalidwrote:
This topic is a FAQ. But I have read the faq and spent a couple of
hours browsing the group archives, and still have a few questions that
I hope you can answer.
My understanding is that recommended practice is to not cast the
return value from malloc(). The rationale for this is that 1) the
cast is not needed and 2) the cast may mask errors.

Right. As you can see 1) is not actually a rationale at all -- its
just a confirmation that it happens to be legal due to the original
design of C, and therefore possible. Its like recommending that you
eat a gallon of whip cream every day because its possible.
Actually, it's quite a good rationale when taken with the very solid
advice that casts should be avoided whenever possible (which, I'll
add, is an equally strong recommendation in C++, since you're trying
to advocate C++ compatibility). Why add a redundant cast when it's
completely unnecessary? When someone advocates casting malloc, I'm
reminded of the following abomination:

(void)printf( "blahblahblah\n" );
And 2) simply does not apply at all on modern compilers -- pretty
much every compiler I use will warn me if I fail to include <stdlib.h>
and yet use malloc().
It silences at least one warning on all of my 'modern' compilers.
Personally, I'd rather have the warning than not, so I don't cast when
I can avoid it. Wise programmers don't hide warnings without extremely
good reason.
This "recommendation" does not have any further basis to it. It also
ignores the obvious counter argument that the cast is necessary to
make the same code compatible with C and C++ (a useful thing, that is
in common practice). Many C++ compilers have vastly superior warnings
and can commonly produce better code, so it very often pays to compile
your ANSI C code with a C++ compiler. C++ compilers, these days, are
better maintained than C compilers.
If you want C++, use C++. Trying to write C++ compatible C, while
disturbingly common, is also surprisingly difficult to get right. The
counter argument has less of a foundation than you claim the original
argument to have.

Yes, it is useful to write C++ compatible C. But only occasionally. I
see this as an exception to the rule and not a reason to ignore the
rule.
I do have the spec (ISO 9899:1999) at my desk, but I am not familiar
enough with it to find the answer to this one. So references to the
spec, possibly along with some interpretation, would also be helpful.

Just keep in mind that the C spec was written in the 80s for a
language designed in the 70s by hackers borrowing from other languages
who were just throwing it together on their way to designing UNIX. A
lot of the things in that spec are of a "historical" or "legacy"
nature.
...
-Jul
Nov 19 '07 #12
On Nov 19, 7:38 am, "Lorenzo Villari" <vll...@tiscali.itwrote:
"Paul Hsieh" <websn...@gmail.comha scritto nel
And 2) simply does not apply at all on modern compilers -- pretty much
every compiler I use will warn me if I fail to include <stdlib.hand yet
use malloc().

Yes. In fact I've always wondered why some people continue to say that...
Because they have an agenda to push. There is literally no
justification for this recommendation, except as a way of enforcing a
needless artificial incompatibility with C++.
Many C++ compilers have vastly superior warnings
and can commonly produce better code, so it very often pays to compile
your ANSI C code with a C++ compiler. C++ compilers, these days, are
better maintained than C compilers.

Ok for the warnings but:

1) Can you give me one example of better code? That would be
interesting...
Urg. I shouldn't have put myself out there, now I can't dig up a
concrete example. I am an avid user of the WATCOM C/C++ compilers.
They decided to supply their C and C++ solutions as two separate
compilers and at various times they have clearly put more effort into
their C++ optimizer. I had some benchmarks somewhere long ago that
demonstrated this.
2) What do you mean by "mantained". Maybe that we have fewer C compilers
than C++ ones? If this is what you meant, I won't be too happy about
that
Well C compilers certainly still exist, and some vendors, like
Microsoft, continue to use a single compiler that compiles both
languages. But GNU, and Watcom have clearly taken the two compiler
approach (but in different ways; GNU uses a common back end, at least
for now.)

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/
Nov 19 '07 #13
On Nov 19, 10:49 am, Julienne Walker <happyfro...@hotmail.comwrote:
On Nov 13, 8:46 pm, Paul Hsieh <websn...@gmail.comwrote:
On Nov 13, 5:14 am, Asbjørn Sæbø <inva...@invalid.invalidwrote:
This topic is a FAQ. But I have read the faq and spent a couple of
hours browsing the group archives, and still have a few questions that
I hope you can answer.
My understanding is that recommended practice is to not cast the
return value from malloc(). The rationale for this is that 1) the
cast is not needed and 2) the cast may mask errors.
Right. As you can see 1) is not actually a rationale at all -- its
just a confirmation that it happens to be legal due to the original
design of C, and therefore possible. Its like recommending that you
eat a gallon of whip cream every day because its possible.

Actually, it's quite a good rationale when taken with the very solid
advice that casts should be avoided whenever possible (which, I'll
add, is an equally strong recommendation in C++, since you're trying
to advocate C++ compatibility).
Without the cast, the code is erroneous and will not compiler on a
correct C++ compiler. In this case the casting is not redundant, as
it specifically create a type check which is realistically helpful in
"cut-paste" situations.
[...] Why add a redundant cast when it's
completely unnecessary? When someone advocates casting malloc, I'm
reminded of the following abomination:

(void)printf( "blahblahblah\n" );
The two have nothing to do with each other. No type checking is
happening here, and there is no functional purpose for it.
And 2) simply does not apply at all on modern compilers -- pretty
much every compiler I use will warn me if I fail to include <stdlib.h>
and yet use malloc().

It silences at least one warning on all of my 'modern' compilers.
But it is an extraneous warning. You are going to get the warning for
using a function without a prototype or implementation anyways (if you
drop the inclusion of stdlib.h) -- that really what the problem is
anyways, not a pointer/int type mismatch.
Personally, I'd rather have the warning than not, so I don't cast when
I can avoid it. Wise programmers don't hide warnings without extremely
good reason.
Wise or not, redundant and misleading warnings for an error you
already have a warning for is not going to help one iota.
This "recommendation" does not have any further basis to it. It also
ignores the obvious counter argument that the cast is necessary to
make the same code compatible with C and C++ (a useful thing, that is
in common practice). Many C++ compilers have vastly superior warnings
and can commonly produce better code, so it very often pays to compile
your ANSI C code with a C++ compiler. C++ compilers, these days, are
better maintained than C compilers.

If you want C++, use C++. Trying to write C++ compatible C, while
disturbingly common, is also surprisingly difficult to get right.
What are you talking about? I write code like that, pretty much
exclusively nowadays. Its not challenging in the least. Certainly
consumers of the Better String Library appreciate it.
[...] The
counter argument has less of a foundation than you claim the original
argument to have.
The original justification is blatantly false. My justification
corresponds to real issues, and real code.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/
Nov 19 '07 #14
CJ
On 13 Nov 2007 at 13:20, Mark Bluemel wrote:
Asbjørn Sæbø wrote:
>My understanding is that recommended practice is to not cast the
return value from malloc(). The rationale for this is that 1) the
cast is not needed and 2) the cast may mask errors.

That is so.
>I assume that the reason the cast is not needed has to do with the
fact that the the pointer returned from malloc() is a void *, and not
a pointer to any other type. (Is that correct?)

Precisely.
>If so, could you explain _why_ (and the details of why) casting the
void pointer is not necessary?

Because according to the standard, pointer to void can be converted to
and from any other object pointer type.
In many older implementations of the standard library, malloc is defined
to return a char * rather than a void *, so including the cast makes
your program more portable.

Nov 19 '07 #15
CJ wrote:
On 13 Nov 2007 at 13:20, Mark Bluemel wrote:
>Because according to the standard, pointer to void can be converted to
and from any other object pointer type.

In many older implementations of the standard library, malloc is defined
to return a char * rather than a void *, so including the cast makes
your program more portable.
That's a very rare corner case. Such libraries probably require
malloc.h as well.

--
Ian Collins.
Nov 19 '07 #16
Julienne Walker wrote, On 19/11/07 18:49:
On Nov 13, 8:46 pm, Paul Hsieh <websn...@gmail.comwrote:
>On Nov 13, 5:14 am, Asbjørn Sæbø <inva...@invalid.invalidwrote:
>>This topic is a FAQ. But I have read the faq and spent a couple of
hours browsing the group archives, and still have a few questions that
I hope you can answer.
My understanding is that recommended practice is to not cast the
return value from malloc(). The rationale for this is that 1) the
cast is not needed and 2) the cast may mask errors.
Right. As you can see 1) is not actually a rationale at all -- its
just a confirmation that it happens to be legal due to the original
design of C, and therefore possible. Its like recommending that you
eat a gallon of whip cream every day because its possible.

Actually, it's quite a good rationale when taken with the very solid
advice that casts should be avoided whenever possible
In fact, you should avoid all code that does not do something useful. It
is more to read that does not help. Casting the result of malloc is one
example where it can actually lead to people not spotting problems.

It should be noted that those most likely not to enable warning about
missing prototypes are also (in my opinion) those most likely to fail to
include stdlib.h and add the cast to "fix" the warning. These people
need to be broken of the habit of adding casts to fix warnings, and
telling them it is OK to cast in the one instance is likely to slow the
breaking of this habit.
(which, I'll
add, is an equally strong recommendation in C++, since you're trying
to advocate C++ compatibility).
The best way to provide compatibility with C++ is normally to compile
your C code as C and use the mechanisms
Why add a redundant cast when it's
completely unnecessary? When someone advocates casting malloc, I'm
reminded of the following abomination:

(void)printf( "blahblahblah\n" );
Agreed.
>And 2) simply does not apply at all on modern compilers -- pretty
much every compiler I use will warn me if I fail to include <stdlib.h>
and yet use malloc().

It silences at least one warning on all of my 'modern' compilers.
Personally, I'd rather have the warning than not, so I don't cast when
I can avoid it. Wise programmers don't hide warnings without extremely
good reason.
Also many compilers will not produce a warning about no prototype on
there default warning levels but *will* provide a warning if there is
stdlib.h has been forgotten and no cast is used.
>This "recommendation" does not have any further basis to it. It also
ignores the obvious counter argument that the cast is necessary to
make the same code compatible with C and C++ (a useful thing, that is
in common practice). Many C++ compilers have vastly superior warnings
and can commonly produce better code, so it very often pays to compile
your ANSI C code with a C++ compiler. C++ compilers, these days, are
better maintained than C compilers.

If you want C++, use C++. Trying to write C++ compatible C, while
disturbingly common, is also surprisingly difficult to get right. The
counter argument has less of a foundation than you claim the original
argument to have.
Indeed. Some code will compile as C or C++ but behave differently
depending on which language you compile it as.
Yes, it is useful to write C++ compatible C. But only occasionally. I
see this as an exception to the rule and not a reason to ignore the
rule.
The only common exception is header files, and those will not in general
include calls to malloc.
>>I do have the spec (ISO 9899:1999) at my desk, but I am not familiar
enough with it to find the answer to this one. So references to the
spec, possibly along with some interpretation, would also be helpful.
Just keep in mind that the C spec was written in the 80s for a
language designed in the 70s by hackers borrowing from other languages
who were just throwing it together on their way to designing UNIX. A
lot of the things in that spec are of a "historical" or "legacy"
nature.
Yes, C has a number of problems due to its legacy. However the changes
that mean casting the value returned by malloc is not needed were quite
deliberate not accidents of history.
--
Flash Gordon
Nov 19 '07 #17
Paul Hsieh wrote:
On Nov 19, 7:38 am, "Lorenzo Villari" <vll...@tiscali.itwrote:
>"Paul Hsieh" <websn...@gmail.comha scritto nel
>>And 2) simply does not apply at all on modern compilers -- pretty much
every compiler I use will warn me if I fail to include <stdlib.hand yet
use malloc().
Yes. In fact I've always wondered why some people continue to say that...

Because they have an agenda to push. There is literally no
justification for this recommendation, except as a way of enforcing a
needless artificial incompatibility with C++.
[...]

(Context: the issue here is casting or not casting the result of malloc().)

Paul, regardless of the technical merits of your argument, your
assertion that those of us who advocate *not* casting the result of
malloc() do so because of some agenda having to do with C++ is
unsupported and false.

Even assuming, for the sake of argument, that you're right and the rest
of us are wrong, please don't presume to make claims about our motives.

My reasons for not casting the result of malloc() have nothing to do
with C++.

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 19 '07 #18
CJ wrote On 11/19/07 14:43,:
[... cast malloc's result or not?]

In many older implementations of the standard library, malloc is defined
to return a char * rather than a void *, so including the cast makes
your program more portable.
The original ANSI Standard was adopted in 1989. Uptake
was rapid (breathtakingly so, by comparison with that of the
1999 revision), but even so it took compiler and library
suppliers a while to grok the Standard, figure out how to
smooth the transition for existing customers, and get new
versions out -- maybe three, four years passed before ANSI-
conforming (by then, ISO-conforming) implementations were
widely available. Let's grant maximum leeway and use four
years; then the older implementations you mention had been
supplanted by 1993.

Windows NT 3.1 shipped in 1993. Question: When you
write software for Windows today, are you careful to stick
to the NT 3.1 API's to enhance portability?

Mosaic 1.0 shipped in 1993. Question: When you write
HTML today, are you careful to use only HTML 1.0 tags to
enhance cross-browser portability?

In the days when malloc() returned `char*', C did not
have prototypes; do you avoid prototypes for portability's
sake? In the days when malloc() returned `char*', there
was no <stdarg.h>; do you shun variadic functions? In the
days when malloc() returned `char*', there was no `void',
no `long double', no stringizing `#', no token-pasting `##',
no '\a' or '\v', no <limits.h>, ... Do you stay away from
all these in an attempt to cater to obsolete compilers and
libraries?

If by some peculiar twist of fate your code winds up
being compiled with Paleolithic library headers, do you
think it's better to have a cast already in place to make
sure you don't get warned of the problem than to be alerted
by a helpful diagnostic?

If you answered "Yes" to any of these questions, you
should cast the result of malloc. After fifteen years on
the island with Gilligan and the gang, a certain amount
of loony behavior is to be expected.

--
Eric.Sosman
Nov 19 '07 #19
On Nov 19, 2:41 pm, Paul Hsieh <websn...@gmail.comwrote:
On Nov 19, 10:49 am, Julienne Walker <happyfro...@hotmail.comwrote:
On Nov 13, 8:46 pm, Paul Hsieh <websn...@gmail.comwrote:
On Nov 13, 5:14 am, Asbjørn Sæbø <inva...@invalid.invalidwrote:
This topic is a FAQ. But I have read the faq and spent a couple of
hours browsing the group archives, and still have a few questions that
I hope you can answer.
My understanding is that recommended practice is to not cast the
return value from malloc(). The rationale for this is that 1) the
cast is not needed and 2) the cast may mask errors.
Right. As you can see 1) is not actually a rationale at all -- its
just a confirmation that it happens to be legal due to the original
design of C, and therefore possible. Its like recommending that you
eat a gallon of whip cream every day because its possible.
Actually, it's quite a good rationale when taken with the very solid
advice that casts should be avoided whenever possible (which, I'll
add, is an equally strong recommendation in C++, since you're trying
to advocate C++ compatibility).

Without the cast, the code is erroneous and will not compiler on a
correct C++ compiler. In this case the casting is not redundant, as
it specifically create a type check which is realistically helpful in
"cut-paste" situations.
*If* you compile as C++, which I've already said can be problematic.
[...] Why add a redundant cast when it's
completely unnecessary? When someone advocates casting malloc, I'm
reminded of the following abomination:
(void)printf( "blahblahblah\n" );

The two have nothing to do with each other. No type checking is
happening here, and there is no functional purpose for it.
Likewise with casting malloc in C. There's no functional purpose for
explicitly requesting a conversion that's already implicit.
And 2) simply does not apply at all on modern compilers -- pretty
much every compiler I use will warn me if I fail to include <stdlib.h>
and yet use malloc().
It silences at least one warning on all of my 'modern' compilers.

But it is an extraneous warning. You are going to get the warning for
using a function without a prototype or implementation anyways (if you
drop the inclusion of stdlib.h) -- that really what the problem is
anyways, not a pointer/int type mismatch.
The standard specifies the warning for using a function without a
prototype as an unspecified common warning. It's not guaranteed to be
produced, which is precisely why you should avoid casting away any
other help you might be getting.
This "recommendation" does not have any further basis to it. It also
ignores the obvious counter argument that the cast is necessary to
make the same code compatible with C and C++ (a useful thing, that is
in common practice). Many C++ compilers have vastly superior warnings
and can commonly produce better code, so it very often pays to compile
your ANSI C code with a C++ compiler. C++ compilers, these days, are
better maintained than C compilers.
If you want C++, use C++. Trying to write C++ compatible C, while
disturbingly common, is also surprisingly difficult to get right.

What are you talking about? I write code like that, pretty much
exclusively nowadays. Its not challenging in the least. Certainly
consumers of the Better String Library appreciate it.
So you're fluent enough in both C and C++ to write code that works
with both without stepping on any toes? Good for you. But not everyone
is as expert as you are. There are far too many subtle differences in
semantics for me to recommend that anyone write "C/C++" unless they're
quite proficient in both languages.

I won't comment on your Better String Library, but a C library
designed to work with C++ does fall under the exception I was talking
about.
[...] The
counter argument has less of a foundation than you claim the original
argument to have.

The original justification is blatantly false. My justification
corresponds to real issues, and real code.
The original justification may be false, but only when you apply your
own restrictions to it. While it's nice that you can successfully
torpedo a rationale that you've butchered into weakness, the same
arguments don't apply fully to the complete rationale.
Nov 19 '07 #20
CJ
On 19 Nov 2007 at 19:51, Ian Collins wrote:
CJ wrote:
>On 13 Nov 2007 at 13:20, Mark Bluemel wrote:
>>Because according to the standard, pointer to void can be converted to
and from any other object pointer type.

In many older implementations of the standard library, malloc is defined
to return a char * rather than a void *, so including the cast makes
your program more portable.
That's a very rare corner case. Such libraries probably require
malloc.h as well.
I'm not sure I'd call it "very rare" - there's plenty of old iron out
there.

Writing in the common subset of K&R C, C89 and C99 where possible costs
you very little, and buys you additional portability.

Nov 19 '07 #21
CJ wrote:
On 19 Nov 2007 at 19:51, Ian Collins wrote:
>CJ wrote:
>>On 13 Nov 2007 at 13:20, Mark Bluemel wrote:
Because according to the standard, pointer to void can be converted to
and from any other object pointer type.
In many older implementations of the standard library, malloc is defined
to return a char * rather than a void *, so including the cast makes
your program more portable.
That's a very rare corner case. Such libraries probably require
malloc.h as well.

I'm not sure I'd call it "very rare" - there's plenty of old iron out
there.

Writing in the common subset of K&R C, C89 and C99 where possible costs
you very little, and buys you additional portability.
Common subset of K&R C and C99?

--
Ian Collins.
Nov 19 '07 #22
CJ wrote, On 19/11/07 22:59:
On 19 Nov 2007 at 19:51, Ian Collins wrote:
>CJ wrote:
>>On 13 Nov 2007 at 13:20, Mark Bluemel wrote:
Because according to the standard, pointer to void can be converted to
and from any other object pointer type.
In many older implementations of the standard library, malloc is defined
to return a char * rather than a void *, so including the cast makes
your program more portable.
That's a very rare corner case. Such libraries probably require
malloc.h as well.

I'm not sure I'd call it "very rare" - there's plenty of old iron out
there.
There is not much when compared to about of post 1995 kit. Personally
I've never needed pre-ANSI compatibility.
Writing in the common subset of K&R C, C89 and C99 where possible costs
you very little, and buys you additional portability.
Well, when I stripped out the handling of pre-ANSI C from a code-base I
needed to work on it made it far easier to read. So the K&R
compatibility was costing a significant amount.
--
Flash Gordon
Nov 19 '07 #23
CJ wrote:
On 19 Nov 2007 at 19:51, Ian Collins wrote:
>CJ wrote:
>>On 13 Nov 2007 at 13:20, Mark Bluemel wrote:
Because according to the standard, pointer to void can be converted to
and from any other object pointer type.
In many older implementations of the standard library, malloc is defined
to return a char * rather than a void *, so including the cast makes
your program more portable.
That's a very rare corner case. Such libraries probably require
malloc.h as well.

I'm not sure I'd call it "very rare" - there's plenty of old iron out
there.

Writing in the common subset of K&R C, C89 and C99 where possible costs
you very little, and buys you additional portability.
It costs you the ability to use prototypes (or at least the ability to
use prototypes without lots of #ifdefs). It also costs you the ability
to assume specific declarations for standard library functions. Let's
see, does malloc() return a void* or a char*? Does it expect a size_t,
or an int, or an unsigned long?

The available dialects of C are basically C99, C90, and N different
pre-ANSI dialects. Catering to pre-ANSI implementations causes the
complexity of writing compatible code to explode.

There may still be some ancient implementations still in use, and if you
really need to worry about that, you have my sympathy. But
<ASSUMPTION>most</ASSUMPTIONC programmers just don't need to worry
about that anymore.

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 20 '07 #24
In article <ba**********************************@b36g2000hsa. googlegroups.com>,
Julienne Walker <ha*********@hotmail.comwrote:
>On Nov 19, 2:41 pm, Paul Hsieh <websn...@gmail.comwrote:
>Without the cast, the code is erroneous and will not compiler on a
correct C++ compiler. In this case the casting is not redundant, as
it specifically create a type check which is realistically helpful in
"cut-paste" situations.

*If* you compile as C++, which I've already said can be problematic.
But problematic enough to be worth the extra checking you get by
compiling it as a different language? Actually, why stop at only one
extra language? I bet if everybody made sure that their code was
acceptable as C, C++, Pascal, Java, Fortran, *and* Haskell, that would
make sure that *ABSOLUTELY NO* incorrect code survived!
dave

Nov 20 '07 #25
Paul Hsieh wrote:
[... on casting the result of malloc() ...]
Without the cast, the code is erroneous and will not compiler on a
correct C++ compiler. [...]
With or without the cast, the code is erroneous and
will not compile with a correct Scheme compiler, Fortran
compiler, PL/1 compiler, Pascal compiler, SNOBOL compiler,
COBOL compiler, or BAL assembler. What's your C problem?

Years ago I saw code that implemented the famous "Hello,
World!" program in C, Fortran, and csh (? some Unix shell,
at any rate) simultaneously. That is, the exact same source
code printed "Hello, World!" when compiled as C, or compiled
as Fortran, or interpreted by csh(?). It was an amusing and
ingenious construct, but not a useful guide to good style in
any one of those three languages.

--
Eric Sosman
es*****@ieee-dot-org.invalid
Nov 20 '07 #26
Julienne Walker wrote:
>
.... snip ...
>
If you want C++, use C++. Trying to write C++ compatible C, while
disturbingly common, is also surprisingly difficult to get right.
The counter argument has less of a foundation than you claim the
original argument to have.

Yes, it is useful to write C++ compatible C. But only occasionally.
I see this as an exception to the rule and not a reason to ignore
the rule.
I consider it totally purposeless. If needed to link C code with
C++ code, that ability is already present in C++. If proposed for
'portability' there are many systems with C compilers that don't
have C++ compilers, but the reverse is not true, or at least very
rare. At the same time any such attempts run into the raw fact
that C++ is not a true superset of C; there are various basic
incompatibilities, which can lead to embarassing failures.

--
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>
Try the download section.

--
Posted via a free Usenet account from http://www.teranews.com

Nov 20 '07 #27
dj******@csclub.uwaterloo.ca.invalid wrote:
In article <ba**********************************@b36g2000hsa. googlegroups.com>,
Julienne Walker <ha*********@hotmail.comwrote:
>On Nov 19, 2:41 pm, Paul Hsieh <websn...@gmail.comwrote:
>>Without the cast, the code is erroneous and will not compiler on a
correct C++ compiler. In this case the casting is not redundant, as
it specifically create a type check which is realistically helpful in
"cut-paste" situations.
*If* you compile as C++, which I've already said can be problematic.

But problematic enough to be worth the extra checking you get by
compiling it as a different language? Actually, why stop at only one
extra language? I bet if everybody made sure that their code was
acceptable as C, C++, Pascal, Java, Fortran, *and* Haskell, that would
make sure that *ABSOLUTELY NO* incorrect code survived!
The difference, of course, is that writing code that compiles
simultaneously as C and Pascal, or as C and Haskell, would be completely
batcrackers insane (unless you're going for deliberate obfuscation).
Writing code that's simultaneously valid in C and C++, on the other
hand, is possible, and there are occasional valid reasons for doing so.
Two examples: P.J. Plauger writes libraries that are valid C and C++
(and is more than competent enough to do so), and if I recall correctly
Kernighan and Ritchie used a C++ compiler to test the code samples in
K&R2 (because C compilers didn't yet support prototypes). The former is
rare, and the latter is no longer much of an issue now that C90 is
widely available.

My personal opinion, in contrast to Paul Hsieh's, is that writing code
that's valid C and C++ is very rarely (not never) a good idea. They're
two different languages, and even though much valid well-written C code
can be valid C++ code, it's rarely valid *well-written* C++ code. Paul
argues that C++ compilers do better checking, but I think that a
properly configured lint tool will do the same checking.

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 20 '07 #28
In article <sl*******************@nospam.com>, CJ <no****@nospam.com>
wrote on Tuesday 20 Nov 2007 4:29 am:
On 19 Nov 2007 at 19:51, Ian Collins wrote:
>CJ wrote:
>>On 13 Nov 2007 at 13:20, Mark Bluemel wrote:
>>>Because according to the standard, pointer to void can be converted
to and from any other object pointer type.

In many older implementations of the standard library, malloc is
defined to return a char * rather than a void *, so including the
cast makes your program more portable.
That's a very rare corner case. Such libraries probably require
malloc.h as well.

I'm not sure I'd call it "very rare" - there's plenty of old iron out
there.

Writing in the common subset of K&R C, C89 and C99 where possible
costs you very little, and buys you additional portability.
While I can understand the problem of maintaining old code, I'd be very
surprised of any current systems which have only a pre-ANSI C compiler
available. Can you give an example?

Nov 20 '07 #29
On Nov 20, 8:43 am, CJ <nos...@nospam.comwrote:
In many older implementations of the standard library, malloc is defined
to return a char * rather than a void *, so including the cast makes
your program more portable.
I wouldn't include other languages (or other versions
of the same language) in my definition of 'portable'.

A portable C89 program means it can be compiled by C89
compilers on any other system that has one.

Would you call it 'enhancing portability' to write your
program in the common subset of C and Perl? Such
programs certainly do exist.
Nov 20 '07 #30
On Nov 20, 11:05 am, Julienne Walker <happyfro...@hotmail.comwrote:
On Nov 19, 2:41 pm, Paul Hsieh <websn...@gmail.comwrote:
What are you talking about? I write code like that, pretty much
exclusively nowadays. Its not challenging in the least. Certainly
consumers of the Better String Library appreciate it.

I won't comment on your Better String Library, but a C library
designed to work with C++ does fall under the exception I was talking
about.
He doesn't write a C library to work with C++. (FWIW, almost every
C library works with C++, with minor header tweaks). He writes code
that can either be compiled as a C library, or as a C++ library.
Nobody can really explain why he does this.
Nov 20 '07 #31
"santosh" <sa*********@gmail.comschrieb im Newsbeitrag
news:fh**********@registered.motzarella.org...
While I can understand the problem of maintaining old code, I'd be very
surprised of any current systems which have only a pre-ANSI C compiler
available. Can you give an example?
Not 100% sure, but I believe with HP/UX you get a pre ANSI Compiler as long
as you don't buy/license a 'real' one (that ancient compiler seems to be
needed/sufficient to create a new kernel)

Bye, Jojo
Nov 20 '07 #32
In article <fh**********@online.de>, Joachim Schmitz
<no*********@schmitz-digital.dewrote on Tuesday 20 Nov 2007 7:03 pm:
"santosh" <sa*********@gmail.comschrieb im Newsbeitrag
news:fh**********@registered.motzarella.org...
>While I can understand the problem of maintaining old code, I'd be
very surprised of any current systems which have only a pre-ANSI C
compiler available. Can you give an example?

Not 100% sure, but I believe with HP/UX you get a pre ANSI Compiler as
long as you don't buy/license a 'real' one (that ancient compiler
seems to be needed/sufficient to create a new kernel)
Understood, but I was asking for an example of a platform where a
pre-ANSI compiler is the _only_ option.

Certain embedded systems might have non-conformant compilers, but that's
(I think) different from a pre-ANSI compiler.

Nov 20 '07 #33
CJ <no****@nospam.comwrote:
On 19 Nov 2007 at 19:51, Ian Collins wrote:
CJ wrote:
In many older implementations of the standard library, malloc is defined
to return a char * rather than a void *, so including the cast makes
your program more portable.
That's a very rare corner case. Such libraries probably require
malloc.h as well.

I'm not sure I'd call it "very rare" - there's plenty of old iron out
there.

Writing in the common subset of K&R C, C89 and C99 where possible costs
you very little, and buys you additional portability.
I'm sorry: writing

func()
short a;
float b;
{
...
}

instead of

int func(short a, float b)
{
...
}

costs very little? You might want to rethink that.

In the case under discussion, casting malloc() calls causes your brain
to rot. To be precise, it causes deterioration, frequently irreversible,
of the parts that let you think "Hey! A cast! Better be careful, there's
something iffy going on here."

Richard
Nov 20 '07 #34
santosh wrote, On 20/11/07 14:26:
In article <fh**********@online.de>, Joachim Schmitz
<no*********@schmitz-digital.dewrote on Tuesday 20 Nov 2007 7:03 pm:
>"santosh" <sa*********@gmail.comschrieb im Newsbeitrag
news:fh**********@registered.motzarella.org...
>>While I can understand the problem of maintaining old code, I'd be
very surprised of any current systems which have only a pre-ANSI C
compiler available. Can you give an example?
Not 100% sure, but I believe with HP/UX you get a pre ANSI Compiler as
long as you don't buy/license a 'real' one (that ancient compiler
seems to be needed/sufficient to create a new kernel)

Understood, but I was asking for an example of a platform where a
pre-ANSI compiler is the _only_ option.
You can also get gcc for HP/UX, so you do not even have to pay to have a
C89/C90/C95 compiler.

I believe there are still a few people using a few ancient machines (or
emulations of them) where the machine itself pre-dates the ANSI standard
by far enough that no one has written an compiler for the target that
supports the standard. I seem to remember someone on comp.std.c
mentioning that they were in this position. I can't remember why they
were using such ancient systems.
Certain embedded systems might have non-conformant compilers, but that's
(I think) different from a pre-ANSI compiler.
It is very different.
--
Flash Gordon
Nov 20 '07 #35

"Paul Hsieh" <we******@gmail.comha scritto nel messaggio
news:2e**********************************@i29g2000 prf.googlegroups.com...
On Nov 19, 7:38 am, "Lorenzo Villari" <vll...@tiscali.itwrote:
"Paul Hsieh" <websn...@gmail.comha scritto nel
Urg. I shouldn't have put myself out there, now I can't dig up a
concrete example. I am an avid user of the WATCOM C/C++ compilers.
They decided to supply their C and C++ solutions as two separate
compilers and at various times they have clearly put more effort into
their C++ optimizer. I had some benchmarks somewhere long ago that
demonstrated this.
2) What do you mean by "mantained". Maybe that we have fewer C
compilers
than C++ ones? If this is what you meant, I won't be too happy
about that

Well C compilers certainly still exist, and some vendors, like
Microsoft, continue to use a single compiler that compiles both
languages. But GNU, and Watcom have clearly taken the two compiler
approach (but in different ways; GNU uses a common back end, at least
for now.)
There's a section in your site in which you do compare the assembler
generated by the watcom compiler, in contrast with one done by hand by you.
Over the first assembler listing I can read:

"WATCOM C/C++ v10.0a output"

so one has the impression they give identical output... but why have you
used the C one anyway ? :)

Nov 20 '07 #36

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Panchi51 | last post by:
Hi, Below is a collection of tips/tricks/caveats for LP64 c coding, full text is at http://www.cs.albany.edu/~mosh/Text/c-ref.txt. Hope it helps, corrections welkome. --...
29
by: Hassan Iqbal | last post by:
hi, in the code below i find that i am able to access p even after i have freed it. not only that the previous values stored in p are accessible even after reallocation of memory to p. please...
20
by: pertheli | last post by:
Hello all What is the difference between Method 1 and Method 2 below? Is Method 2 safe to use? typedef short Word; typedef unsigned char Char; int nAllocSize = large number;
11
by: ma740988 | last post by:
How would I modify the TEST_CMD function to essentially return the appropriate status? Simply put. TEST_CMD could return either status1 or status2. The return value will be passed to the Write...
231
by: Brian Blais | last post by:
Hello, I saw on a couple of recent posts people saying that casting the return value of malloc is bad, like: d=(double *) malloc(50*sizeof(double)); why is this bad? I had always thought...
7
by: Ioannis Vranos | last post by:
I came across in clc++ this by chance: "There is no language construct for dynamically allocating multidimensional arrays. See the comp.lang.c FAQ question 6.16 and related questions: ...
25
by: Why Tea | last post by:
Thanks to those who have answered my original question. I thought I understood the answer and set out to write some code to prove my understanding. The code was written without any error checking....
101
by: Tinkertim | last post by:
Hi, I have often wondered if casting the return value of malloc() (or friends) actually helps anything, recent threads here suggest that it does not .. so I hope to find out. For instance : ...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.