473,805 Members | 2,074 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

(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 2105
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**********@p obox.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*****@invali d.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**********@p obox.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.nordic semi.no>,
Asbjørn Sæbø <in*****@invali d.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
--
"Considerat ion 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**********@a ioe.org>,
Mark Bluemel <ma**********@p obox.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
--
"Considerat ion 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**********@p obox.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_Keit h) 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...@invali d.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...@invali d.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

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

Similar topics

2
5748
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. -- Panchi51<et>pacbell.net LP64 Gotcha List ----------------
29
2026
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 some one explain it to me. what does malloc and free do here? thanks, hassan #include<stdio.h>
20
11465
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
677
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 function inside main. The prototype for the Write function is highlighted below. #define TRUE 1 #define FALSE 0
231
23256
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 (perhaps mistakenly) that the purpose of a void pointer was to cast into a legitimate date type. Is this wrong? Why, and what is considered to be correct form?
7
1218
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: http://www.eskimo.com/~scs/C-faq/q6.16.html
25
2269
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. --- #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct {
101
4366
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 : char *tmp = NULL;
0
9718
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9596
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10613
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10363
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10368
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9186
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5544
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5678
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
3008
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.