Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > (FAQ details:) malloc(), void * and casts

Reply
Thread Tools

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

 
 
=?utf-8?b?QXNiasO4cm4gU8OmYsO4?=
Guest
Posts: n/a
 
      11-13-2007

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ø
 
Reply With Quote
 
 
 
 
Mark Bluemel
Guest
Posts: n/a
 
      11-13-2007
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.
 
Reply With Quote
 
 
 
 
Richard Tobin
Guest
Posts: n/a
 
      11-13-2007
In article <(E-Mail Removed)>,
Asbjørn Sæbø <(E-Mail Removed)> wrote:

>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.
 
Reply With Quote
 
Richard Tobin
Guest
Posts: n/a
 
      11-13-2007
In article <fhc8al$9kt$(E-Mail Removed)>,
Mark Bluemel <(E-Mail Removed)> 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.


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.
 
Reply With Quote
 
Richard
Guest
Posts: n/a
 
      11-13-2007
Asbjørn Sæbø <(E-Mail Removed)> writes:

> 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ø

 
Reply With Quote
 
=?utf-8?b?QXNiasO4cm4gU8OmYsO4?=
Guest
Posts: n/a
 
      11-13-2007
Mark Bluemel <(E-Mail Removed)> writes:

> 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


 
Reply With Quote
 
Mark Bluemel
Guest
Posts: n/a
 
      11-13-2007
Asbjørn Sæbø wrote:
> Mark Bluemel <(E-Mail Removed)> writes:
>
>> 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.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      11-13-2007
Mark Bluemel <(E-Mail Removed)> writes:
> Asbjrn Sb 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) http://www.velocityreviews.com/forums/(E-Mail Removed) <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"
 
Reply With Quote
 
Paul Hsieh
Guest
Posts: n/a
 
      11-14-2007
On Nov 13, 5:14 am, Asbjrn Sb <(E-Mail Removed)> wrote:
> 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.h> and 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/

 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      11-14-2007
Paul Hsieh wrote:
> Asbjrn Sb <(E-Mail Removed)> wrote:
>
>> 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.h> and 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

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
What is the difference between void proba(); and void proba(void); ??? PencoOdStip@gmail.com C++ 1 05-23-2007 07:12 PM
Are implicit casts to void*& illegal? Ray Gardener C++ 3 04-19-2006 08:55 AM
what is the difference, void func(void) and void fucn() noblesantosh@yahoo.com C Programming 5 07-22-2005 04:38 PM
"void Method()" vs "void Method(void)" Ollej Reemt C++ 7 04-22-2005 03:47 AM
`void **' revisited: void *pop(void **root) Stig Brautaset C Programming 15 10-28-2003 09:03 AM



Advertisments