473,421 Members | 1,627 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,421 software developers and data experts.

why is casting malloc a bad thing?

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?

thanks,

Brian Blais

Nov 14 '05
231 22888
Papadopoulos Giannis <ip******@inf.uth.gr> wrote:
Richard Bos wrote:
Papadopoulos Giannis <ip******@inf.uth.gr> wrote:
Richard Bos wrote:

>d = malloc(50*sizeof(*d));
>--------------------------
>o the sortest way

Nope. Lose the parens around *d, then it's the shortest.

I like 'em..


Hey, I'm not disputing your choice, only the denomination "shortest". If
you want to write ugly code, be my guest :-)


Ugly style or not, I got used to it and it is really difficult to adopt
a new style...

Anyone who does not like my code, has always the choice of a
beautifier... And I don't think it's all that bad...


Of course. De gustibus, &c. It's just that _I_ think it's ugly, and as
everybody should know, in matters of taste I am always right ;-)

Richard
Nov 14 '05 #151
qe*@pobox.com (Paul Hsieh) wrote:
Papadopoulos Giannis <ip******@inf.uth.gr> wrote:
d = malloc(50*sizeof(*d));
--------------------------
o the sortest way
They all generate equivalent object code


Non sequitur.
o the most portable


Its not portable to anal C++ compilers set at their most pedantic
warning level.


Well, duh. It's not portable to Pascal compilers, either. C is not C++.
o does remember you to include stdlib


Or malloc.h on some systems.


If they're broken, perhaps. Which would explain a lot.
On AMD64 (aka x86-64) pointers have long long (or __int64)
representation. On 16bit DOS systems pointers can have a kind of
int[2] representation. In general pointers should not be assumed to
be of size int


Or, indeed, equivalent to _any_ kind of integer.
o it gives a good hint on what d's type is


Actually the declaration of d is the only credible source of what type
d is.


Quite.

Richard
Nov 14 '05 #152
Paul Hsieh wrote:
Papadopoulos Giannis wrote:

d = (double*)malloc( 50*sizeof(double) ); [...] o it gives a good hint on what d's type is


Actually the declaration of d is the only credible source of what type
d is.


There are three situations where the types of d and *d are relevant:

Assign a value: d[10] = 1.5;
Read a value: a[5] = d[10] * 5.3;

Low level memory management including pointer arithmetic:
d = malloc(50 * sizeof(*d));
memcpy(&d[10], &a[5], 5 * sizeof(*d));
a = d + 10;

The latter examples will work for any type of *d, assuming that *a has
the same type. In fact, the type does not matter at all. If you (P.
Giannis) like a good hint in these situations, you will love a good
hint for assign and read, since you will get unexpected results when
d[10] is an integer type. Then, hungarian notation might be the tool
for you, making things worse.
Holger
Nov 14 '05 #153
Joona I Palaste <pa*****@cc.helsinki.fi> wrote

You are right. Stroustrup's opinion matters on C++, and your opinion
matters on C2, but neither of your (neither's of you?) opinion matters
on C. C++ is Stroustrup's language and C2 is yours, fine, you can keep
them. Neither of you has claim over C.


On the other hand, my opinions on C matters as much as any other
experienced and long-term member of the C community and contributor to
the C language. The fact that I designed C++ doesn't disqualify me
from having valid opinions on C. This is especially true as I present
my opinions in the context of tectnical arguments, rather than as glib
snippets in postings. For example, see my papers on C/C++
compatibility, which you can download from
http://www.research.att.com/~bs/papers.html

-- Bjarne Stroustrup; http://www.research.att.com/~bs
Nov 14 '05 #154
Bjarne Stroustrup <bs@research.att.com> scribbled the following:
Joona I Palaste <pa*****@cc.helsinki.fi> wrote
You are right. Stroustrup's opinion matters on C++, and your opinion
matters on C2, but neither of your (neither's of you?) opinion matters
on C. C++ is Stroustrup's language and C2 is yours, fine, you can keep
them. Neither of you has claim over C.
On the other hand, my opinions on C matters as much as any other
experienced and long-term member of the C community and contributor to
the C language. The fact that I designed C++ doesn't disqualify me
from having valid opinions on C. This is especially true as I present
my opinions in the context of tectnical arguments, rather than as glib
snippets in postings. For example, see my papers on C/C++
compatibility, which you can download from
http://www.research.att.com/~bs/papers.html


You are right about that, of course. You are an experienced C programmer
and your opinion about C matters just as much as any other experienced C
programmer's. But the fact that you invented C++ doesn't make your
opinion about C any more special than anyone else's. It just makes your
opinion about _C++_ more special.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"Show me a good mouser and I'll show you a cat with bad breath."
- Garfield
Nov 14 '05 #155
Papadopoulos Giannis <ip******@inf.uth.gr> wrote in message news:<bv***********@ulysses.noc.ntua.gr>...
Brian Blais wrote:
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?

thanks,

Brian Blais

I' ve read nearly completely the whole thread, although in the way I
lost my path.

I assume the following:

d = malloc(50*sizeof(*d));
--------------------------
o the sortest way
o the most portable
o does remember you to include stdlib


You have to #include stdlib.h (or somehow have the correct prototype)
regardless.
o changing type of d does not affect anything
o it looks a bit funny
On the contrary, it looks perfectly normal to me.

d = malloc(50*sizeof(double));
------------------------------
o changing type of d is disastrous

Maybe, maybe not. If you change d to a smaller type, you just
allocated more memory than you needed. Internal fragmentation is
never good, but it's not always disastrous.
d = (double*)malloc( 50*sizeof(double) );
-----------------------------------------
o does not want stdlib (but aren't all pointers unsigned ints? - enlight
me plz)
You still have to #include stdlib.h, or somehow have a correct
prototype in scope. Without a prototype in scope, malloc() is assumed
to return int, which may or may not have the same size as a void *.
This means the return value may be truncated or stored incorrectly.
The cast *does not* obviate the need for a correct prototype. All the
cast does is convert the (potentially garbage) return value into a
(potentially invalid) pointer to double.

Pointers need not be the same size or representation as unsigned ints.
Pointers to different types need not be the same size or
representation; e.g., a pointer to int may have a different size and
representation from a pointer to void.
o it gives a good hint on what d's type is
Unless someone changed the type of d.
ď if you change d's type it tells you so

Am I missing anything else???

Nov 14 '05 #156
Richard Bos wrote:
How are casts from malloc() superfluous? Code should work identically
whether the casts are there or not.


Yes. Which is why they're superfluous.


No. Code does not work identically.
However, code that uses casts is
different from that which does not in cases of failure to properly
declare malloc(). In that case they convert a int into a pointer.


Erm... no. They convert something the programmer _thinks_ is a pointer,
but has implicitly _declared_ to be an int, and which may not actually
exist or have a valid value, into a pointer. Without so much as a
warning.


How does that invalidate what I said? Whether the programmer thinks so
or not, it does convert an int to pointer. Some int, from somewhere. My
point was that casts on malloc() aren't superfluous, which means more
than what is needed, they just plain are different in this context.

Even when a proper declaration for malloc() is in scope, there are the
cases where there is a pointer mismatch:

int *p;

p = (double *)malloc(sizeof (double));
Still not superfluous in this case. The code works differently without
the cast.
I personally going to stick with no cast. And I think the general case
of C++ compatibility is a non-starter for most applications. I don't
write C code to compiler under C++. When I want C++, I write it.


Brian Rodenborn
Nov 14 '05 #157
In <XT*****************@nwrddc01.gnilink.net> "P.J. Plauger" <pj*@dinkumware.com> writes:
Sorry, that's not quite right. The cast wasn't required in many/most
early C compilers. Some compilers experimented with stronger type
checking for pointers (a bit of the prior art we drew on when we
decided it was safe and advisable to add stronger type checking
in Standard C). Some of us felt that better documentation of
intended type conversions was advisable. But for whatever reason,
Kernighan at least went through a period when he saw fit to write
the casts.


IIRC, the pre-ANSI C mallloc returned char *. That required an
explicit cast any time its return value was not assigned to a char *.
So, it is very likely that Kernighan was doing it out of habit.

But there is another reason, mentioned in the preface:

We used Bjarne Stroustrup's C++ translator extensively for local
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
testing of our programs, and Dave Kristol provided us with an ANSI
^^^^^^^^^^^^^^^^^^^^^^^
C compiler for final testing.

Since C++ requires the cast, the authors had no chance but to use it.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #158
On 26 Jan 2004 20:50:02 GMT, mw*****@newsguy.com (Michael Wojcik)
wrote:

In article <8_********************@comcast.com>, "Mark Bruno" <ya*************@yahoo.com> writes:
Stroutstrup himself has said that all good-style C programs are also C++
programs, so it's just better style.


I am continually amazed at people who think Stroustrop (I assume this
is whom you meant) magically gets the last word in this argument. He
clearly has an interest in promoting C++, and that very likely
includes persuading C programmers to switch. What makes you think
he's an impartial observer? For that matter, what makes you think
he's right?


Stroustrop uses English carefully, and what he stated (in "The C++
Programming Language Third Edition") is subtly different, and compared
to Mark Bruno's statement above, defensible and correct. He actually
states "However, *good* C programs tend to be C++ programs. For
example, every program in Kernighan and Ritchie, The C Programming
Language, 2nd Edition, is a C++ program."(emphasis in the original).

In an appendix he gives an exhaustive treatment of when, and why, C
programs are not C++ programs, and when the two are semantically
different.
Nov 14 '05 #159
On Tue, 27 Jan 2004 00:38:34 GMT, in comp.lang.c , "P.J. Plauger"
<pj*@dinkumware.com> wrote:
"Mark McIntyre" <ma**********@spamcop.net> wrote in message
news:mi********************************@4ax.com.. .
On Mon, 26 Jan 2004 00:29:24 GMT, in comp.lang.c , "P.J. Plauger"
<pj*@dinkumware.com> wrote:
>What I find interesting about this debate is the two positions being
>espoused:


Correct. But not these two. The two positions are

1) putting in malloc casts is perfectly ok, its harmless.
2) putting in malloc casts is unnecessary and therefore not ok.


I'm beginning to understand the communication problem here.
I've never espoused either of these posiitons, but that seems
to be what you've read.


I'm finding it hard to read your postings in another way. You're on
record as saying you think that the casts should be there. Charitably
that puts you in group 1.
As I said, I respect you enormously. You mistake intolerance of your
one stupidity for lack of respect


Uh yes, I *do* consider intolerance a lack of respect.


What, you don't have any coworkers or friends who have some small
thing that annoys you? Bullshit, to coin a phrase.
>A closed mind avoids the risk of having to change.


I'd not know, I don't have one.


And yet you can be intolerant. An interesting pair of positions
to reconcile.


When you can explain why, I'll be interested to read it.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #160
On Tue, 27 Jan 2004 00:55:08 GMT, in comp.lang.c , "P.J. Plauger"
<pj*@dinkumware.com> wrote:
"Mark McIntyre" <ma**********@spamcop.net> wrote in message
news:dl********************************@4ax.com.. .
Anyway to respond to you now, sorry, but I won't retract. I've read
through his reasoning several times, and its IMHO wrong. Since he
persists in holding a wrong position, I consider him idiotic on this
point.
Note that this isn't a general position, merely on the malloc point.


I've now accumulated enough evidence that you're incapable of
reading accurately what others write, particularly when you don't
agree with them.


The only way you can have achieved that accumulation is by failing to
read properly what I've written myself. So I propose to stop being
interested in your postings, to avoid further unpleasantness.
We've been over it many many times, and while I appreciate his work
circumstances make it much more convenient for him to cast malloc,
thats not a valid reason for advocating it to C programmers.


And you haven't even noticed that I'm *not* advocating this
position to C programmers in general.


Then your powers of explaination are much less good than you think.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #161
On Tue, 27 Jan 2004 00:48:38 GMT, in comp.lang.c , "P.J. Plauger"
<pj*@dinkumware.com> wrote:
"Mark McIntyre" <ma**********@spamcop.net> wrote in message
news:qs********************************@4ax.com.. .
I recognised it very well indeed, and I elected to post anyway,
because I believe that when it comes to malloc casts, PJ has the
programming equivalent of a crush on a beautiful but unsuitable woman,
and is unable to see that she's stealing his money, sleeping with his
friends and using his house to sell dope from.... :-)
Now you're simply being a jerk.


And you, sir, have absolutely no sense of humour whatsoever. Come on,
you dolt, I'm not being nasty to you, you have one blind spot, I
forgive you, now grow up.
From your earlier posting:


(snip completely irrelevant requote)

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #162
Allin Cottrell wrote:
Sidney Cadot wrote:
With Mr. Plauger, I am amazed by the complete inability demonstrated
by many of the 'anti-cast' crowd to admit even a hint of nuance in
their thought process on this issue. Being 'pro-cast' myself...
As I see it, as a member of the 'anti-cast' crowd, the problem is
with the very notion of a 'pro-cast' position (a la Tisdale). We
see no possible rationale for this in terms of the C programming
language.
And that's ok for me. Limiting oneself to the context of the C
programming language (thus waiving the C++ compatibility argument for a
moment), I can see only one defense for malloc casting, which I
personally think is an important one: rigorous type discipline. if I
look at the free-standing expression "malloc(50*sizeof(double))" it is
clear that this should by intent be of type double*, but it is in fact
of type void*. I correct the compilers' misconception about this type by
a cast.

I know that in most contexts this isn't necessary because it will be
assigned to a typed pointer immediately after, but still it brings the
expression under the compiler's type checking regime a little bit
earlier, preventing such silliness as:

int *x = malloc(50*sizeof(double));

since

int *x = (double *)malloc(50*sizeof(double));

is an error.

Now I've seen all the counter-arguments to this by now, but in the end I
simply feel that malloc(50*sizeof(double)) is incorrectly typed as
void*, and that's all there is to it as far as I am concerned. Most here
disagree, their argumentation is clear and not without merit. I do feel
however that my stand on this is quite defensible, and will keep saying
so until either I or the whole lot of you changes sides ;-)
On the other hand, P.J. Plauger's basic position seems perfectly
reasonable, namely that there are some special contexts where a
body of code has to be compiled indifferently as C or as C++, and
in those special contexts casting the return from malloc is
required (and does no harm if we can assume that the coder is
astute enough to ensure that <stdlib.h> is always #included).

This, it seems to me, is not a 'pro-cast' position: it's just
saying that real-world considerations other than "good C
programming" sometimes dictate a cast. Fair enough.


Yes. Above, I try to put up a defense for the more extreme 'pro-cast'
position that doesn't invoke the C++ scenario. Feel free to dismiss it.

Best regards,

Sidney

Nov 14 '05 #163
Sidney Cadot wrote:
Limiting oneself to the context of the C
programming language (thus waiving the C++ compatibility argument for a
moment), I can see only one defense for malloc casting, which I
personally think is an important one: rigorous type discipline. if I
look at the free-standing expression "malloc(50*sizeof(double))" it is
clear that this should by intent be of type double*, but it is in fact
of type void*. I correct the compilers' misconception about this type by
a cast.

I know that in most contexts this isn't necessary because it will be
assigned to a typed pointer immediately after, but still it brings the
expression under the compiler's type checking regime a little bit
earlier, preventing such silliness as:

int *x = malloc(50*sizeof(double));


Of course, that sort of silliness is taken care of (even if many lines
separate the

int *x;

from the malloc() call), by the clc recommended practice of

int *x = malloc(50 * sizeof *x);

--
Allin Cottrell
Department of Economics
Wake Forest University, NC
Nov 14 '05 #164
In <bv**********@news.tudelft.nl> Sidney Cadot <si****@jigsaw.nl> writes:
I know that in most contexts this isn't necessary because it will be
assigned to a typed pointer immediately after, but still it brings the
expression under the compiler's type checking regime a little bit
earlier, preventing such silliness as:

int *x = malloc(50*sizeof(double));

since

int *x = (double *)malloc(50*sizeof(double));

is an error.

Now I've seen all the counter-arguments to this by now, but in the end I
simply feel that malloc(50*sizeof(double)) is incorrectly typed as
void*, and that's all there is to it as far as I am concerned.


In most cases, malloc(50*sizeof(double)) is considered bad style.
Consider the alternative:

double *x = malloc(50 * sizeof *x);

Casting to double * not only doesn't add anything, because there is no
place left for the error you're talking about, but it is a maintenance
headache if the type of x ever needs to be changed, say to pointer
to long double: instead of making one change, you have to make two,
for no redeeming advantage.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #165
Da*****@cern.ch (Dan Pop) wrote in message news:<bv***********@sunnews.cern.ch>...
In <XT*****************@nwrddc01.gnilink.net> "P.J. Plauger" <pj*@dinkumware.com> writes:
Sorry, that's not quite right. The cast wasn't required in many/most
early C compilers. Some compilers experimented with stronger type
checking for pointers (a bit of the prior art we drew on when we
decided it was safe and advisable to add stronger type checking
in Standard C). Some of us felt that better documentation of
intended type conversions was advisable. But for whatever reason,
Kernighan at least went through a period when he saw fit to write
the casts.


IIRC, the pre-ANSI C mallloc returned char *. That required an
explicit cast any time its return value was not assigned to a char *.
So, it is very likely that Kernighan was doing it out of habit.

But there is another reason, mentioned in the preface:

We used Bjarne Stroustrup's C++ translator extensively for local
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
testing of our programs, and Dave Kristol provided us with an ANSI
^^^^^^^^^^^^^^^^^^^^^^^
C compiler for final testing.

Since C++ requires the cast, the authors had no chance but to use it.


Dennis Ritchie and Brian Kernighan are among the most thoughtful of
people. They did have a choice at the time. If they had thought it
important/best to leave malloc calls uncast they could have (1) used
the ANSI C compiler or (2) edited the casts out in the final draft
(after the final check with the ANSI C compiler) or (3) politely asked
me for a compatibility feature in Cfront (we talked almost every day).

I think it is safest to assume that when Dennis Ritchie and Brian
Kernighan did something, it was because they wanted to do that and not
the opposite.

-- Bjarne Stroustrup; http://www.research.att.com/~bs
Nov 14 '05 #166
In <18**************************@posting.google.com > bs@research.att.com (Bjarne Stroustrup) writes:
Da*****@cern.ch (Dan Pop) wrote in message news:<bv***********@sunnews.cern.ch>...
In <XT*****************@nwrddc01.gnilink.net> "P.J. Plauger" <pj*@dinkumware.com> writes:
>Sorry, that's not quite right. The cast wasn't required in many/most
>early C compilers. Some compilers experimented with stronger type
>checking for pointers (a bit of the prior art we drew on when we
>decided it was safe and advisable to add stronger type checking
>in Standard C). Some of us felt that better documentation of
>intended type conversions was advisable. But for whatever reason,
>Kernighan at least went through a period when he saw fit to write
>the casts.


IIRC, the pre-ANSI C mallloc returned char *. That required an
explicit cast any time its return value was not assigned to a char *.
So, it is very likely that Kernighan was doing it out of habit.

But there is another reason, mentioned in the preface:

We used Bjarne Stroustrup's C++ translator extensively for local
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
testing of our programs, and Dave Kristol provided us with an ANSI
^^^^^^^^^^^^^^^^^^^^^^^
C compiler for final testing.

Since C++ requires the cast, the authors had no chance but to use it.


Dennis Ritchie and Brian Kernighan are among the most thoughtful of
people. They did have a choice at the time. If they had thought it
important/best to leave malloc calls uncast they could have (1) used
the ANSI C compiler or (2) edited the casts out in the final draft
(after the final check with the ANSI C compiler) or (3) politely asked
me for a compatibility feature in Cfront (we talked almost every day).

I think it is safest to assume that when Dennis Ritchie and Brian
Kernighan did something, it was because they wanted to do that and not
the opposite.


They officially "repented" for doing it. See the K&R2 errata at
http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html

142(§6.5, toward the end): The remark about casting the return value of
malloc ("the proper method is to declare ... then explicitly coerce")
needs to be rewritten. The example is correct and works, but the advice
is debatable in the context of the 1988-1989 ANSI/ISO standards. It's
not necessary (given that coercion of void * to ALMOSTANYTYPE * is
automatic), and possibly harmful if malloc, or a proxy for it, fails
to be declared as returning void *. The explicit cast can cover up an
unintended error. On the other hand, pre-ANSI, the cast was necessary,
and it is in C++ also.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #167
Bjarne Stroustrup <bs@research.att.com> scribbled the following:
Dennis Ritchie and Brian Kernighan are among the most thoughtful of
people. They did have a choice at the time. If they had thought it
important/best to leave malloc calls uncast they could have (1) used
the ANSI C compiler or (2) edited the casts out in the final draft
(after the final check with the ANSI C compiler) or (3) politely asked
me for a compatibility feature in Cfront (we talked almost every day). I think it is safest to assume that when Dennis Ritchie and Brian
Kernighan did something, it was because they wanted to do that and not
the opposite.


At the risk of sounding like an idiot, I have to ask you what you mean
by "the opposite". Do you mean that Ritchie and Kernighan did <X>
because they wanted to do <X> instead of the opposite of <X>? Or do
you mean that they did something because they wanted to do it, not
because they didn't want to do it?

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"Roses are red, violets are blue, I'm a schitzophrenic and so am I."
- Bob Wiley
Nov 14 '05 #168
"P.J. Plauger" <pj*@dinkumware.com> wrote:
"Richard Bos" <rl*@hoekstra-uitgeverij.nl> wrote in message
news:40****************@news.individual.net...
"P.J. Plauger" <pj*@dinkumware.com> wrote:
If you write malloc calls without casts, it's not because it's
necessarily good programming practice but because your grandfather did.
I would find it slightly insulting that an otherwise respectable
programmer like yourself would assume that I hadn't actually thought
about the matter, if it hadn't been you and this particular dispute.


Sorry, I was being cute at the cost of some precision. And I certainly
didn't intend to be insulting with that statement


I know you didn't. That's one reason why, it coming from you, I wasn't
insulted.
My point was that you *can* write malloc calls
without casts only because the C committee gave them special
dispensation.


But this isn't true! You can write malloc() calls without casts because
malloc() returns void *. Now, void pointers have special dispensation
from needing casts; but this has nothing specifically to do with
malloc(). It's a general property of void *s, also often used in qsort()
callback functions, for example.
As it is, I'll just state, flatly, that you're bloody wrong.


I have trouble feeling wrong when I'm trying to state a more
ecumenical position than damn near anybody else in this thread.


Your ecumenicality on casts has nothing to do with the above sentence;
you are simply provably wrong on _my_ position on casts, which is a
level of opinionatedness extra :-).
IOW, regardless of which of us is right about casts, you're wrong about
_me_.
avoid casts as much as possible, and I _do_ think that that is
necessarily good programming practice, and neither of my grandfathers
programmed, so I formed my own opinion on this.


It's fine with me if you adopt this style, particularly having thought
it through. It's less fine that you and others absolutely refuse to
let in the possibility that well meaning people might arrive at a
different conclusion on such a delicate matter of style.


Ah, well, you see, that's because I've ever only heard of three
arguments for the cast, and several against; and those against are of
higher quality than those for.

For the casts, we have "I have customers who need to compile this on all
kinds of compilers, and I cannot hand-gear my code for every single
situation" (you, and AFAICT, nobody else); "But it breaks when I compile
my C code on my C++ compiler!!!" (all newbies in the world, seemingly,
and Tisdale); and "The code with the cast is more solid and type-safe"
(several kinds of trolls and confused newbies).
The first argument, yours, holds some water, but only in exceptional
circumstances. Now, _you_, in fact, are in exceptional circumstances,
being an implementation writer and creator of code for others, so this
argument holds water for you. I don't think I've ever seen anyone else
in c.l.c to whom it applies, though.
To the second argument, one need only say "Well, don't do that, then",
just as to people who complain that their C code won't compile as Java.
As for the third argument, it is demonstrably false; and has been shown
to be false repeatedly in this newsgroup.
If you know of any other argument _for_ the casts, one which applies to
your average programmer and not just to someone who, like you, has
special requirements, and one which actually stands the test of c.l.c,
I'd love to hear it.

Against casting malloc(), we have several arguments, ranging from
shorter typing and less cluttered code, through the demonstration that
code without the cast, written properly, is actually _more_ solid than
code with it, to my own more philosophical argument that _any_ warning
sign is bad when over-used, because it devaluates the warning where it
is necessary; the "cry wolf" argument. All of those have been argued
more than once (or twice, or a thousand times) here; I have never seen
any of them properly refuted.

In the end, then, we may come across as somewhat curt, sometimes; but
that is because all these arguments have already been brought forward,
they're now just being re-hashed over and over again, and we've all
already made up our minds, in a perfectly rational way, a long time ago.
And each time Mr. Tisdale, or someone else, pulls out yet another
re-statement of the same tired old "but C is just C++ stripped down, and
I want to compile C as C++", we, at least I, do get just a little weary.
But that doesn't mean we haven't thought about it. We _have_, over and
over again; that's the reason.

Richard
Nov 14 '05 #169
On Wed, 28 Jan 2004, Richard Bos wrote:
As for the third argument, it is demonstrably false; and has been shown
to be false repeatedly in this newsgroup.


AFAICT it has /not/ been shown false. The lack of malloc
casts could actually hide undefined behaviors:

#include <stdio.h>
#include <stdlib.h>

double *x; /* Wrong declaration */

int
main(void)
{
x = (int *) malloc(sizeof *x);
if (x) {
*x = 4;
printf("%d\n", *x); /* Undefined behavior */
free(x);
}
return 0;
}

With the malloc cast, you are guaranteed a diagnostic.
Without the cast, the diagnostic is not required. Bad style
perhaps, but this possibility should not be dismissed.

Tak-Shing

Nov 14 '05 #170
Dan Pop wrote:
In <bv**********@news.tudelft.nl> Sidney Cadot <si****@jigsaw.nl> writes:

I know that in most contexts this isn't necessary because it will be
assigned to a typed pointer immediately after, but still it brings the
expression under the compiler's type checking regime a little bit
earlier, preventing such silliness as:

int *x = malloc(50*sizeof(double));

since

int *x = (double *)malloc(50*sizeof(double));

is an error.

Now I've seen all the counter-arguments to this by now, but in the end I
simply feel that malloc(50*sizeof(double)) is incorrectly typed as
void*, and that's all there is to it as far as I am concerned.

In most cases, malloc(50*sizeof(double)) is considered bad style.
Consider the alternative:

double *x = malloc(50 * sizeof *x);


That's funny, my lone expression seems to have turned into a full-blown
declarator/initializer as if by magic.

My point, as you know by now but choose to ignore, is that the malloc
expression itself should be properly typed as a double*.
Casting to double * not only doesn't add anything, because there is no
place left for the error you're talking about, but it is a maintenance
headache if the type of x ever needs to be changed, say to pointer
to long double: instead of making one change, you have to make two,
That's true. In fact, it's more of a "maintenance headache" than what
your preferred notation introduces when changing the identifier name
(but only slightly).
for no redeeming advantage.


The redeeming advantage, to me, is the knowledge that I have corrected
the misconception of the compiler about the type of an object at the
earliest possible opportunity.

That way, I don't have to rely on the semantics of C with regard to
allowing void*-to-any* assignments, which I think are an ugly wart on
C's type safety system.

An analogy may help. Here in Holland, it aggrieves me to say, we have no
law forbidding the wearing of white socks under a suit. But that doesn't
mean I don't make an effort to avoid being dressed like that.

Best regards,

Sidney

Nov 14 '05 #171
I have not seen the base article, hence my response to this:
Da*****@cern.ch (Dan Pop) wrote in message news:<bv***********@sunnews.cern.ch>...
IIRC, the pre-ANSI C mallloc returned char *. That required an
explicit cast any time its return value was not assigned to a char *.
So, it is very likely that Kernighan was doing it out of habit.


It did indeed return a char *. And no, it did not require an explicit
cast any time its return value was not assigned to a char *. Pre-ANSI
C did not require casts on pointer assignments, the requirement came
with ANSI C.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Nov 14 '05 #172
In <bv**********@news.tudelft.nl> Sidney Cadot <si****@jigsaw.nl> writes:
Dan Pop wrote:
In <bv**********@news.tudelft.nl> Sidney Cadot <si****@jigsaw.nl> writes:

I know that in most contexts this isn't necessary because it will be
assigned to a typed pointer immediately after, but still it brings the
expression under the compiler's type checking regime a little bit
earlier, preventing such silliness as:

int *x = malloc(50*sizeof(double)); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
since

int *x = (double *)malloc(50*sizeof(double)); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
is an error.

Now I've seen all the counter-arguments to this by now, but in the end I
simply feel that malloc(50*sizeof(double)) is incorrectly typed as
void*, and that's all there is to it as far as I am concerned.

In most cases, malloc(50*sizeof(double)) is considered bad style.
Consider the alternative:

double *x = malloc(50 * sizeof *x);


That's funny, my lone expression seems to have turned into a full-blown
declarator/initializer as if by magic.


No magic at all: you have used it as such, in your own examples. Hence
my counterexample.
My point, as you know by now but choose to ignore, is that the malloc
expression itself should be properly typed as a double*.
Nope, because it never used as an expression by itself: it's always used
either as an initialiser or as a subexpression of a wider expression
which establishes its intended type.
Casting to double * not only doesn't add anything, because there is no
place left for the error you're talking about, but it is a maintenance
headache if the type of x ever needs to be changed, say to pointer
to long double: instead of making one change, you have to make two,


That's true. In fact, it's more of a "maintenance headache" than what
your preferred notation introduces when changing the identifier name
(but only slightly).


If you ever have to change identifier names in your code, there is
something very wrong with your coding methodology.
for no redeeming advantage.


The redeeming advantage, to me, is the knowledge that I have corrected
the misconception of the compiler about the type of an object at the
earliest possible opportunity.


The compiler has no misconceptions about anything.
That way, I don't have to rely on the semantics of C with regard to
allowing void*-to-any* assignments, which I think are an ugly wart on
C's type safety system.
I'm afraid that few C programmers share your views.
An analogy may help. Here in Holland, it aggrieves me to say, we have no
law forbidding the wearing of white socks under a suit. But that doesn't
mean I don't make an effort to avoid being dressed like that.


So, what kind of socks are you wearing under a white suit?

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #173
In <Hs********@cwi.nl> "Dik T. Winter" <Di********@cwi.nl> writes:
I have not seen the base article, hence my response to this:
Da*****@cern.ch (Dan Pop) wrote in message news:<bv***********@sunnews.cern.ch>...
IIRC, the pre-ANSI C mallloc returned char *. That required an
explicit cast any time its return value was not assigned to a char *.
So, it is very likely that Kernighan was doing it out of habit.


It did indeed return a char *. And no, it did not require an explicit
cast any time its return value was not assigned to a char *. Pre-ANSI
C did not require casts on pointer assignments, the requirement came
with ANSI C.


A certain Dennis M. Ritchie seems to be thinking otherwise. From the
K&R2 errata (I've already posted the full quote):

On the other hand, pre-ANSI, the cast was necessary, and it is in
C++ also.

K&R1 explains the dangers of omitting the cast, at page 192.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #174
Richard Heathfield wrote:
when both sides are using
words like "idiot" and "nonsense". I dread to think what must be going
through the newbies' heads as they read your exchange with Mr Plauger.

We're loving it! Don't stop.

Nov 14 '05 #175
Dan Pop wrote:
In <bv**********@news.tudelft.nl> Sidney Cadot <si****@jigsaw.nl> writes:
Dan Pop wrote:
In <bv**********@news.tudelft.nl> Sidney Cadot <si****@jigsaw.nl> writes:

I know that in most contexts this isn't necessary because it will be
assigned to a typed pointer immediately after, but still it brings the
expression under the compiler's type checking regime a little bit
earlier, preventing such silliness as:

int *x = malloc(50*sizeof(double));
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
since

int *x = (double *)malloc(50*sizeof(double));
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
is an error.

Now I've seen all the counter-arguments to this by now, but in the end I
simply feel that malloc(50*sizeof(double)) is incorrectly typed as
void*, and that's all there is to it as far as I am concerned.
In most cases, malloc(50*sizeof(double)) is considered bad style.
Consider the alternative:

double *x = malloc(50 * sizeof *x);
That's funny, my lone expression seems to have turned into a full-blown
declarator/initializer as if by magic.

No magic at all: you have used it as such, in your own examples. Hence
my counterexample.


Ah, yes. I was trying to make a point about the expression
'malloc(50*sizeof(double))', but I can see where the confusion comes from.
My point, as you know by now but choose to ignore, is that the malloc
expression itself should be properly typed as a double*.


Nope, because it never used as an expression by itself: it's always used
either as an initialiser or as a subexpression of a wider expression
which establishes its intended type.

Unfortunately, all examples where the result of malloc() is not
immediately assigned (or something similar) look contrived, yes. That
doesn't invalidate the point. This fact-of-life is incidental, not
essential, for the purpose of this discussion.
Casting to double * not only doesn't add anything, because there is no
place left for the error you're talking about, but it is a maintenance
headache if the type of x ever needs to be changed, say to pointer
to long double: instead of making one change, you have to make two,


That's true. In fact, it's more of a "maintenance headache" than what
your preferred notation introduces when changing the identifier name
(but only slightly).


If you ever have to change identifier names in your code, there is
something very wrong with your coding methodology.


To me, that sounds like a bizarre statement. Please elaborate.
for no redeeming advantage.


The redeeming advantage, to me, is the knowledge that I have corrected
the misconception of the compiler about the type of an object at the
earliest possible opportunity. The compiler has no misconceptions about anything.


I disagree. Provided the malloc has succeeded, there is a bunch of
consecutive bytes floating around, intended to be used as a double
array. Such a bunch of bytes should properly be typed double *.

Unfortunately, the C language lacks a new operator that yields a
properly typed result. We have to make do with malloc, which has little
choice other than to return a void *. This constraint of the language
leads to the weird situation that a pointer to memory area that should
be properlt typed is not (yet) properly typed. I think it's right to
call this a misconception on the side of the compiler, and I think it's
right to correct this.
That way, I don't have to rely on the semantics of C with regard to
allowing void*-to-any* assignments, which I think are an ugly wart on
C's type safety system.


I'm afraid that few C programmers share your views.


I'm afraid you're right.
An analogy may help. Here in Holland, it aggrieves me to say, we have no
law forbidding the wearing of white socks under a suit. But that doesn't
mean I don't make an effort to avoid being dressed like that.


So, what kind of socks are you wearing under a white suit?


I have no idea. My analogy invertor comes up empty.

Best regards,

Sidney

Nov 14 '05 #176
Sidney Cadot wrote:
[...]
My point, as you know by now but choose to ignore, is that the malloc
expression itself should be properly typed as a double*.
[...]
The redeeming advantage, to me, is the knowledge that I have corrected
the misconception of the compiler about the type of an object at the
earliest possible opportunity.

That way, I don't have to rely on the semantics of C with regard to
allowing void*-to-any* assignments, which I think are an ugly wart on
C's type safety system.


Do you rely on the promotion rules? Do you think that the rules with
all the implicit conversions between signed/unsigned int types, float,
double, etc. for numbers provide more type safety than the void* to
any* conversions for pointers? Or do you always write something like
this:

char c = (char)((int)'0' + (int)9);

As I previously wrote far below in the thread, there are three
situations where, for a pointer d, the types of d and *d are relevant:

Assignment: d[10] = 5.3;
Read + arithmetics: a[5] = d[10] * 1.7;

Low level memory management including pointer arithmetic:
d = malloc(50 * sizeof(*d));
memcpy(&d[10], &a[5], 5 * sizeof(*d));
a = d + 10;

What happens when the types of d and a are changed to int*? The memory
functions will work perfectly without change, in fact the type does
not matter at all. For the above assignment and read, you will get an
unexpected result for a[5]. Do you care for it with casts? Caring for
the type where the language provides anything to completely abstract
it away, and not caring for it where it really matters is at least a
bit inconsequent, IMHO.
Holger
Nov 14 '05 #177
Holger Hasselbach wrote:
Sidney Cadot wrote:
[...]
My point, as you know by now but choose to ignore, is that the malloc
expression itself should be properly typed as a double*.
[...]
The redeeming advantage, to me, is the knowledge that I have corrected
the misconception of the compiler about the type of an object at the
earliest possible opportunity.

That way, I don't have to rely on the semantics of C with regard to
allowing void*-to-any* assignments, which I think are an ugly wart on
C's type safety system.

Do you rely on the promotion rules? Do you think that the rules with
all the implicit conversions between signed/unsigned int types, float,
double, etc. for numbers provide more type safety than the void* to
any* conversions for pointers? Or do you always write something like
this:

char c = (char)((int)'0' + (int)9);


I rely on the rules that I think are reasonable. This includes your
sample case (so I don't use casts there), and things like implicit
int-to-float conversion.

I do not rely on the rules that I think are unreasonable. This includes
implicit void*-to-any* conversions, but also implicit float-to-int
conversions.

So I would never write:

intVar = floatVar;

But I would always use an explicit cast (and only in cases where I do
not care too much about rounding).
As I previously wrote far below in the thread, there are three
situations where, for a pointer d, the types of d and *d are relevant:
Only three?
Assignment: d[10] = 5.3;
Read + arithmetics: a[5] = d[10] * 1.7;

Low level memory management including pointer arithmetic:
d = malloc(50 * sizeof(*d));
memcpy(&d[10], &a[5], 5 * sizeof(*d));
a = d + 10;

What happens when the types of d and a are changed to int*? The memory
functions will work perfectly without change, in fact the type does
not matter at all. For the above assignment and read, you will get an
unexpected result for a[5].
I think "unexpected" is a very subjective term... I do not think
anything would happen that I did not expect.
Do you care for it with casts?
As stated above, I make an effort to avoid implicit float-to-int
conversions.
Caring for
the type where the language provides anything to completely abstract
it away, and not caring for it where it really matters is at least a
bit inconsequent, IMHO.


Mastery of any subject is not about knowing the rules, but perhaps more
about good judgement about when to break them.

(Not that it applies of course, but it sounds quite profound)

Best regards,

Sidney

Nov 14 '05 #178
On Mon, 26 Jan 2004 22:54:26 GMT,
P.J. Plauger <pj*@dinkumware.com> wrote
in Msg. <CU***************@nwrddc01.gnilink.net>
1) Style rules should be developed by considering all applicable
principles and weighing their various importance *for that particular
rule*.


So if you write a function that expects a void pointer but uses another
type internally (like the compare function for qsort), would you do it
like this?

int foo(void *a)
{
struct whatever_struct *s = (struct whatever_struct *) a;
/* ... */
}

--Daniel

--
"With me is nothing wrong! And with you?" (from r.a.m.p)
Nov 14 '05 #179
On Wed, 28 Jan 2004 18:49:52 +0000,
Tak-Shing Chan <es***@city.ac.uk> wrote
in Msg. <Pine.GSO.4.33.0401281740480.18387-100000@swindon>
On Wed, 28 Jan 2004, Richard Bos wrote:
As for the third argument, it is demonstrably false; and has been shown
to be false repeatedly in this newsgroup.


AFAICT it has /not/ been shown false. The lack of malloc
casts could actually hide undefined behaviors:

#include <stdio.h>
#include <stdlib.h>

double *x; /* Wrong declaration */

int
main(void)
{
x = (int *) malloc(sizeof *x);


When you start casting x here, why not cast it everywhere you use it? This
doesn't have to do with malloc().

--Daniel

--
"With me is nothing wrong! And with you?" (from r.a.m.p)
Nov 14 '05 #180
On 26 Jan 2004 13:42:11 GMT,
Mark A. Odell <no****@embeddedfw.com> wrote
in Msg. <Xn********************************@130.133.1.4>
Why would a C++ compiler need to worry about malloc()'ing code? They have
memory allocation schemes of their own in C++.


....and indeed, IIRC, you're recommended to only use new to allocate memory
in C++ anyway; malloc() is considered bad style. Which gives us yet
another reason against the cast: When C++ balks about an uncast malloc()
it's time to change it to "new" instead (and to get rid of the
corresponding free() as well). But this is OT on clc.

--Daniel

--
"With me is nothing wrong! And with you?" (from r.a.m.p)
Nov 14 '05 #181
On Thu, 29 Jan 2004 01:08:46 +0100,
Sidney Cadot <si****@jigsaw.nl> wrote
in Msg. <bv**********@news.tudelft.nl>
That's true. In fact, it's more of a "maintenance headache" than what
your preferred notation introduces when changing the identifier name
(but only slightly).


Changing an (presumably unique) identifier name is a piece of cake unless
you use a mechanical typewriter for writing source code. But automatically
changing the multiply-used type of an object with a text editor is a bit
more difficult.

--Daniel

--
"With me is nothing wrong! And with you?" (from r.a.m.p)
Nov 14 '05 #182
On Thu, 29 Jan 2004 01:08:46 +0100,
Sidney Cadot <si****@jigsaw.nl> wrote
in Msg. <bv**********@news.tudelft.nl>
That way, I don't have to rely on the semantics of C with regard to
allowing void*-to-any* assignments,


When programming in C you have to rely on the semantics of C with regard
to pretty much anything.

--Daniel

--
"With me is nothing wrong! And with you?" (from r.a.m.p)
Nov 14 '05 #183
Tak-Shing Chan <es***@city.ac.uk> wrote:
On Wed, 28 Jan 2004, Richard Bos wrote:
As for the third argument, it is demonstrably false; and has been shown
to be false repeatedly in this newsgroup.
AFAICT it has /not/ been shown false. The lack of malloc
casts could actually hide undefined behaviors:


Not unless there is more wrong.
#include <stdio.h>
#include <stdlib.h>

double *x; /* Wrong declaration */
Very unusual. Generally one knows what kind of data one wants when one
declares it; only while using them do you sometimes get confused.
int
main(void)
{
x = (int *) malloc(sizeof *x);
if (x) {
*x = 4;
printf("%d\n", *x); /* Undefined behavior */
You know, I'd expect to get a warning; and I'd expect malloc()-casters
to cast away that warning by writing

printf("%d\n", (int)*x);

or even

printf("%d\n", *(int *)x);
With the malloc cast, you are guaranteed a diagnostic.
Without the cast, the diagnostic is not required. Bad style
perhaps, but this possibility should not be dismissed.


Actually, I do dismiss this possibility, because I don't believe it
happens that way.

Moreover, it is not a reason to cast malloc() in particular. Would you
also expect to see the cast on

int *y;

y = (int *)x;

If not, why make an exception for malloc()?

Richard
Nov 14 '05 #184
Daniel Haude wrote:

On Mon, 26 Jan 2004 22:54:26 GMT,
P.J. Plauger <pj*@dinkumware.com> wrote
in Msg. <CU***************@nwrddc01.gnilink.net>
1) Style rules should be developed by considering all applicable
principles and weighing their various importance *for that particular
rule*.


So if you write a function that expects a void pointer but uses
another type internally (like the compare function for qsort),
would you do it like this?

int foo(void *a)
{
struct whatever_struct *s = (struct whatever_struct *) a;
/* ... */
}


No.

struct whatever_struct *s = a;

a needs to be holding a valid (struct whatever_struct *) type
value to begin with, or your code's no good.

void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *))
{
unsigned char swap, *p1, *p2, *end, *array, *i, *j, *k, *after;
size_t bytes;

array = base;
after = nmemb * size + array;
if (nmemb > (size_t)-1 / 3) {
nmemb = (size_t)-1 / 3;
}
do {
bytes = nmemb * size;
for (i = bytes + array; i != after; i += size) {
j = i - bytes;
if (compar(j, i) > 0) {
k = i;
do {
p1 = j;
p2 = k;
end = p2 + size;
do {
swap = *p1;
*p1++ = *p2;
*p2++ = swap;
} while (p2 != end);
if (bytes + array > j) {
break;
}
k = j;
j -= bytes;
} while (compar(j, k) > 0);
}
}
nmemb = nmemb != 2 ? 3 * nmemb / 8 : 1;
} while (nmemb);
}

--
pete
Nov 14 '05 #185
Well I am not sure to measure upto u guys, my question may be redundnant.
My question is this, if people pretend with their own arguments
that casting malloc return may cause undefined behaviour, I would like
to know

double* p = malloc(8*sizeof(double));==>OK for some here because
implicit coversion is well enough
but why
double* p = (double*) malloc(8*sizeof(double));==>NOK for some.

I assume that casting the malloc's return is just an indication for my
codevelopers who may see an assignement of p from a malloc a 500 or more
lines after my pointer declaration p.

If we prentend that implicit conversion is safe and the fact of casting
may cause UB due to probable alignement problems, its a bit difficult to
understant why implicit conversion may be safer than an explicit more
than a matter of style.
Does compilers treat them differently?


Nov 14 '05 #186
Sidney Cadot wrote:
Holger Hasselbach wrote:
Do you rely on the promotion rules? Do you think that the rules with
all the implicit conversions between signed/unsigned int types, float,
double, etc. for numbers provide more type safety than the void* to
any* conversions for pointers? Or do you always write something like
this:

char c = (char)((int)'0' + (int)9);


I rely on the rules that I think are reasonable. This includes your
sample case (so I don't use casts there), and things like implicit
int-to-float conversion.

I do not rely on the rules that I think are unreasonable. This includes
implicit void*-to-any* conversions, but also implicit float-to-int
conversions.

So I would never write:

intVar = floatVar;

But I would always use an explicit cast (and only in cases where I do
not care too much about rounding).


Occasionally I use explicit casts in that case, too, to silence
over-paranoid compilers ("It's my intention to be unprecise, so shut
up!"). In full awareness that it could introduce serious unwarned bugs
when the intVar is later changed to a longVar without modifying the
cast, when the type is not abstracted by a typedef. But that's another
thing than to not rely on it. To not rely on it has something of to
not trust its correctness of implementation or the correctness of the
rules themself.

Why exactly do you think that the float-to-int conversion is
unreasonable?

Do you think that an explicit conversion is "more correct" than an
implicit one? I'm quite sure that any existing conforming compiler
will produce exactly the same result in intVar for both cases.

Why exactly do you think that the void*-to-any* conversion is
unreasonable? What exactly could go wrong in the implicit semantics?

Did you have any situations where you experienced the failure of the
implicit conversions (in both int and void), which you successfully
cured with an explicit cast? And that you could blame on the
semantics, not on a broken non-conforming compiler?
As I previously wrote far below in the thread, there are three
situations where, for a pointer d, the types of d and *d are relevant:


Only three?


Can you give another one that does not fit into one of these three?

[...]
Holger
Nov 14 '05 #187
magesh <ma*****@club-internet.fr> wrote:
Well I am not sure to measure upto u guys, my question may be redundnant.
My question is this, if people pretend with their own arguments
that casting malloc return may cause undefined behaviour,


Nonsense - nobody has "pretended" that. Casting malloc() may _hide_
undefined behaviour which is present in the code whether there is a cast
or not. If you call malloc() without a declaration in scope for it, you
always invoke undefined behaviour. The cast doesn't change that fact.
What it does do is stop the compiler from telling you about it.

Richard
Nov 14 '05 #188
Richard Bos wrote:
magesh <ma*****@club-internet.fr> wrote:

Well I am not sure to measure upto u guys, my question may be redundnant.
My question is this, if people pretend with their own arguments
that casting malloc return may cause undefined behaviour,

Nonsense - nobody has "pretended" that. Casting malloc() may _hide_
undefined behaviour which is present in the code whether there is a cast
or not. If you call malloc() without a declaration in scope for it, you
always invoke undefined behaviour. The cast doesn't change that fact.

What it does do is stop the compiler from telling you about it.


No, it does not actually. This argument may have been relevant 10 years
ago, but it is no longer. Sure, it's not a required diagnostic in C89
mode, but any halfway decent compiler is able to warn about an
undeclared malloc() nowadays.

If you don't use the appropriate command line options to enable such
warnings, that's more of a problem than casting malloc results can ever be.

In short, I think this argument is stale, and is getting staler all the
time.

Best regards, Sidney

Nov 14 '05 #189
magesh wrote:
Well I am not sure to measure upto u guys, my question may be redundnant.
My question is this, if people pretend with their own arguments
that casting malloc return may cause undefined behaviour, I would like
to know
Nobody is pretending that. Both sides agree that not including
<stdlib.h> before using malloc() is very wrong, it is this which causes
UB. Casting or not casting the result of malloc will not lead to
undefined behavior in itself.
double* p = malloc(8*sizeof(double));==>OK for some here because
implicit coversion is well enough
but why
double* p = (double*) malloc(8*sizeof(double));==>NOK for some.
It's not ok for some (most, actually) for what I'd like to call
stylistic reasons.
I assume that casting the malloc's return is just an indication for my
codevelopers who may see an assignement of p from a malloc a 500 or more
lines after my pointer declaration p.
If you can show me a plausible scenario for this, I'd welcome it. In
practice, malloc() results are almost always assigned to a typed pointer.
If we prentend that implicit conversion is safe
No reason to pretend, it is safe (for the result of malloc, anyway).
and the fact of casting
may cause UB due to probable alignement problems,
Not for a malloc() result, which is guaranteed to be properly aligned
for conversion to basically any type of pointer.
its a bit difficult to
understant why implicit conversion may be safer than an explicit more
than a matter of style.
It is claimed to be safer more from a code-maintenance point of view. In
this respect, some valid arghments do indeed exist.
Does compilers treat them differently?


As far as I know, there are no circumstances where x=y (with x of type
T* and y of type void*) yields a different semantics than x=(T*)y ; if
this is true, it is probable that any real-life compiler will treat
these equivalently.

Best regards,

Sidney
Nov 14 '05 #190
Daniel Haude wrote:
On Thu, 29 Jan 2004 01:08:46 +0100,
Sidney Cadot <si****@jigsaw.nl> wrote
in Msg. <bv**********@news.tudelft.nl>
That way, I don't have to rely on the semantics of C with regard to
allowing void*-to-any* assignments,

When programming in C you have to rely on the semantics of C with regard
to pretty much anything.


Not at all. For example, I do not have to rely on the semantics of
trigraphs, since I avoid them like the plague.

Best regards, Sidney

Nov 14 '05 #191
Daniel Haude wrote:
On Thu, 29 Jan 2004 01:08:46 +0100,
Sidney Cadot <si****@jigsaw.nl> wrote
in Msg. <bv**********@news.tudelft.nl>
That's true. In fact, it's more of a "maintenance headache" than what
your preferred notation introduces when changing the identifier name
(but only slightly).

Changing an (presumably unique) identifier name is a piece of cake unless
you use a mechanical typewriter for writing source code. But automatically
changing the multiply-used type of an object with a text editor is a bit
more difficult.


It is good to see we are in utter agreement :-)

Best regards, Sidney

Nov 14 '05 #192
Sidney Cadot <si****@jigsaw.nl> wrote:
Richard Bos wrote:
magesh <ma*****@club-internet.fr> wrote:
Well I am not sure to measure upto u guys, my question may be redundnant.
My question is this, if people pretend with their own arguments
that casting malloc return may cause undefined behaviour,


Nonsense - nobody has "pretended" that. Casting malloc() may _hide_
undefined behaviour which is present in the code whether there is a cast
or not. If you call malloc() without a declaration in scope for it, you
always invoke undefined behaviour. The cast doesn't change that fact.

What it does do is stop the compiler from telling you about it.


No, it does not actually. This argument may have been relevant 10 years
ago, but it is no longer. Sure, it's not a required diagnostic in C89
mode, but any halfway decent compiler is able to warn about an
undeclared malloc() nowadays.


And a halfway decent compiler _should_ not warn about problems you have
explicitly cast away.

Richard
Nov 14 '05 #193
Holger Hasselbach wrote:
So I would never write:

intVar = floatVar;

But I would always use an explicit cast (and only in cases where I do
not care too much about rounding).

Occasionally I use explicit casts in that case, too, to silence
over-paranoid compilers ("It's my intention to be unprecise, so shut
up!"). In full awareness that it could introduce serious unwarned bugs
when the intVar is later changed to a longVar without modifying the
cast, when the type is not abstracted by a typedef. But that's another
thing than to not rely on it. To not rely on it has something of to
not trust its correctness of implementation or the correctness of the
rules themself.


Sure, ok. I rely on my compiler to follow the defined semantics, sure,
but I am in disagreement with some semantics, so I avoid relying on
them. Not because of distrust, but because of dislike.

In this respect, implicit void*-to-any* conversion, implicit
float-to-int conversion, and use of trigraphs are in the same "don't do
this" category, in my book.
Why exactly do you think that the float-to-int conversion is
unreasonable?
Because the conversion is inherently impossible to do right without loss
of information, for the mathematical objects that underly floats and
integers.

There's a clear distinction between integers and floats for me, which is
that, within range, the integers behave exactly like their mathematical
cousins. This is not true for floats, they are inherently an
approximation, which I /always/ keep in mind when working with them. For
this reason, I'm not much bothered by int-to-float conversions.
Do you think that an explicit conversion is "more correct" than an
implicit one? I'm quite sure that any existing conforming compiler
will produce exactly the same result in intVar for both cases.
They are semantically equivalent, but not stylistically.
Why exactly do you think that the void*-to-any* conversion is
unreasonable? What exactly could go wrong in the implicit semantics?
There's not so much wrong with void*-to-any* conversion, other than the
fact that it may be done implicitly. This, in my (unpopular) opinion,
allows for what I consider "sloppy typing":

double *x = malloc(50*sizeof *x);

I firmly believe that the right-hand-side expression should be converted
to the proper type (double *) before doing /anything/ with it (including
assigment). But I am probably alone in thinking that, in this particular
crowd.
Did you have any situations where you experienced the failure of the
implicit conversions (in both int and void), which you successfully
cured with an explicit cast? And that you could blame on the
semantics, not on a broken non-conforming compiler?


No. My style comes from armchair reasoning, not bad experiences.
As I previously wrote far below in the thread, there are three
situations where, for a pointer d, the types of d and *d are relevant:


Only three?

Can you give another one that does not fit into one of these three?


I think that for a pointer d, the types of d and *d are relevant in any
context where it is used, and I believe there are more than three
contexts. But then, you probably meant something more specific.

Best regards,

Sidney

Nov 14 '05 #194
In <bv**********@news.tudelft.nl> Sidney Cadot <si****@jigsaw.nl> writes:
Dan Pop wrote:
If you ever have to change identifier names in your code, there is
something very wrong with your coding methodology.


To me, that sounds like a bizarre statement. Please elaborate.


The only *good* reason for renaming an identifier is because the original
name was improperly chosen. Hence my "bizarre" statement above.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #195
In <40******@news2.power.net.uk> Richard Heathfield <in*****@address.co.uk.invalid> writes:
informed opinion); and thank heaven for that, when both sides are using
words like "idiot" and "nonsense". I dread to think what must be going
through the newbies' heads as they read your exchange with Mr Plauger.


Sooner or later, they're bound to discover that Mark McIntyre is clc's
resident idiot and Mr Plauger the author or coauthor of a number of
highly appreciated books about programming.

Of course, this doesn't mean that the former can't right or the latter
can't be wrong, merely that it is highly improbable.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #196
Sidney Cadot wrote:
magesh wrote:
Well I am not sure to measure upto u guys, my question may be redundnant.
My question is this, if people pretend with their own arguments
that casting malloc return may cause undefined behaviour, I would like
to know

Nobody is pretending that. Both sides agree that not including
<stdlib.h> before using malloc() is very wrong, it is this which causes
UB. Casting or not casting the result of malloc will not lead to
undefined behavior in itself.


I completely agree with the fact that proper header files should be
included, I would be amazed a proper C file that never calls a function
from stdlib, so normal programmers include them, if they give attention
to warnings from the compiler or else this thread is not meant for them.
double* p = malloc(8*sizeof(double));==>OK for some here because
implicit coversion is well enough
but why
double* p = (double*) malloc(8*sizeof(double));==>NOK for some.

It's not ok for some (most, actually) for what I'd like to call
stylistic reasons.


Thats what I think, but I agree with fact that unnecessary casts may
fool the compiler and prevent from warning, if not properly used.
I assume that casting the malloc's return is just an indication for my
codevelopers who may see an assignement of p from a malloc a 500 or
more lines after my pointer declaration p.

If you can show me a plausible scenario for this, I'd welcome it. In
practice, malloc() results are almost always assigned to a typed pointer.


declaration of p 1000 lines before.
1001: p= malloc(sizeof(*p)*10);
or
those who don't care of memory
1001: p= malloc(1024);

could you tell me what type is p, while u are going through just this
part of ur code.

1001: p= (int*)malloc(sizeof(int)*10);

Thought it appears newbie ,I think this is more explicit!

Reagrding code maintenance, the other solution p= malloc(sizeof(*p)*10);
may be easy to change the type of p without changing the malloc line in
ur code, after that?? the fact that the type of p has changed may have
more impact on other lines where u use them, than those on one malloc
statement!!!

If we prentend that implicit conversion is safe

No reason to pretend, it is safe (for the result of malloc, anyway).
and the fact of casting may cause UB due to probable alignement problems,

Not for a malloc() result, which is guaranteed to be properly aligned
for conversion to basically any type of pointer.
its a bit difficult to understant why implicit conversion may be safer
than an explicit more than a matter of style.

It is claimed to be safer more from a code-maintenance point of view. In
this respect, some valid arghments do indeed exist.
Does compilers treat them differently?

As far as I know, there are no circumstances where x=y (with x of type
T* and y of type void*) yields a different semantics than x=(T*)y ; if
this is true, it is probable that any real-life compiler will treat
these equivalently.

Yep thats what I expect too.
Best regards,

Sidney

Thanks for ur reply,
regards,
magesh
Nov 14 '05 #197
In <bv**********@news.tudelft.nl> Sidney Cadot <si****@jigsaw.nl> writes:
Richard Bos wrote:
magesh <ma*****@club-internet.fr> wrote:

Well I am not sure to measure upto u guys, my question may be redundnant.
My question is this, if people pretend with their own arguments
that casting malloc return may cause undefined behaviour,

Nonsense - nobody has "pretended" that. Casting malloc() may _hide_
undefined behaviour which is present in the code whether there is a cast
or not. If you call malloc() without a declaration in scope for it, you
always invoke undefined behaviour. The cast doesn't change that fact.

What it does do is stop the compiler from telling you about it.


No, it does not actually. This argument may have been relevant 10 years
ago, but it is no longer. Sure, it's not a required diagnostic in C89
mode, but any halfway decent compiler is able to warn about an
undeclared malloc() nowadays.

If you don't use the appropriate command line options to enable such
warnings, that's more of a problem than casting malloc results can ever be.

In short, I think this argument is stale, and is getting staler all the
time.


Try a reality check: how many newbies have you seen enabling such
warnings when they show the way they compiled their code (quite often,
people posting here show their compilation command line)?

And keep in mind that this discussion is focused on newbies, experienced
programmers have already defined their preference pro or con casting
void pointers and it is not this thread that is going to make them change
their minds (you will keep casting when this discussion is over, I will
keep avoiding such casts as the plague).

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #198
Dan Pop wrote:
Sidney Cadot <si****@jigsaw.nl> writes:
Dan Pop wrote:
If you ever have to change identifier names in your code,
there is something very wrong with your coding methodology.


To me, that sounds like a bizarre statement. Please elaborate.


The only *good* reason for renaming an identifier is because
the original name was improperly chosen. Hence my "bizarre"
statement above.


Names are originally chosen to make sense to the originator, at
that time. There are many occasions for revision, most of which
are for additional clarity or distinguishment. I keep a utility
around to make mass multiple identifier changes across multiple
files in single passes, and find it very useful at times.

The purpose of the software, the identity of the originator, and
the time are all subject to change, so "improper" is not the
appropriate description.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

Nov 14 '05 #199
On Fri, 30 Jan 2004, Richard Bos wrote:
Tak-Shing Chan <es***@city.ac.uk> wrote:
[snip]
#include <stdio.h>
#include <stdlib.h>

double *x; /* Wrong declaration */
Very unusual. Generally one knows what kind of data one wants when one
declares it; only while using them do you sometimes get confused.


Have you written any program generators? Are all of them
zero-defect implementations?
int
main(void)
{
x = (int *) malloc(sizeof *x);
if (x) {
*x = 4;
printf("%d\n", *x); /* Undefined behavior */


You know, I'd expect to get a warning;


Which part of the standard mandates such warnings?
and I'd expect malloc()-casters
to cast away that warning by writing

printf("%d\n", (int)*x);

or even

printf("%d\n", *(int *)x);
Your implication that malloc()-casters are doing so just to
shut up the warnings is at best a faulty generalization. When I
do cast malloc, I am trying to get /more/ warnings, not less.
Note that I abhor useless casts, too, so I would never cast this:

int *x = malloc(sizeof *x);

because the type of x is crystal clear in this context. Now,
perhaps, having a mix of casted and uncasted mallocs in the same
translation unit would have the best of both worlds--detecting
missing <stdlib.h> and at the same time detecting type errors:

int *x = malloc(128 * sizeof *x);
if (x) {
foo(128, TYPE_IS_INTEGER, x);
free(x);
}
:
:
:
x = (int *) malloc(2048 * sizeof *x);
if (x) {
bar(2048, TYPE_IS_INTEGER, x);
free(x);
}
With the malloc cast, you are guaranteed a diagnostic.
Without the cast, the diagnostic is not required. Bad style
perhaps, but this possibility should not be dismissed.


Actually, I do dismiss this possibility, because I don't believe it
happens that way.


Yet, it just happened in the above program.
Moreover, it is not a reason to cast malloc() in particular. Would you
also expect to see the cast on

int *y;

y = (int *)x;

If not, why make an exception for malloc()?


No, because the purpose of the diagnostic is to prompt the
programmer to fix the wrong declaration of x. The diagnostic
produced by y = x is a clue to the observant programmer that a
problem has occurred with the type of x or y. On the other hand,
there is not enough information for the implementation to
diagnose the problem in x = malloc(sizeof *x).

Tak-Shing

Nov 14 '05 #200

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

Similar topics

33
by: hermit_crab67 | last post by:
Can someone explain to a C newbie why this doesn't work as I expect it to work? (expectations clearly outlined in the printf statement in main routine) OS: Linux 2.4.26 GCC: 2.95.4 void...
35
by: ytrama | last post by:
Hi, I have read in one of old posting that don't cast of pointer which is returned by the malloc. I would like to know the reason. Thanks in advance, YTR
32
by: alex.j.k2 | last post by:
Hello all, I have "PRECISION" defined in the preprocessor code and it could be int, float or double, but I do not know in the code what it is. Now if I want to assign zero to a "PRECISION"...
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
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...
0
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...
1
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...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
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,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.