Casting of void pointer returned by malloc()

I

Ian Collins

That's great so long as sizeof *p makes some sort of sense. If you
are doing the struct hack, then this is irrelevant. Besides you can
still mis-synch the p with the variable you are assigning, so this is
not of much help. And, of course, this "alternative" doesn't
accomplish any positive affect at all (besides satisfying the neuroses
of some people in this group) versus the much simpler and safer
In C++ (which was your initial point) you get a type safe wrapper to malloc.
#define typeMalloc(type,qty) ((type *) malloc((qty)*sizeof(type)))

You can just compare it on safety, on cut and paste, simplicity, and
compatibility with C++. And the arguments against it, that are
repeated here over and over, are just blatantly false.
For starters, you have to change the type in two places if you change
the type of the objects being allocated, also (at least with C++) you
have a macro where a function is more appropriate.

Your sig is still broken.
 
Y

Yevgen Muntyan

Ian said:
In C++ (which was your initial point) you get a type safe wrapper to malloc.

Would be indeed nice if C code writers also wrote C++ wrappers. And
python bindings, for completeness.
For starters, you have to change the type in two places if you change
the type of the objects being allocated,

Yeah, we are changing types all the time, so much that it becomes a pain
to erase the old type name and enter new one.
also (at least with C++) you
have a macro where a function is more appropriate.

With C++, you have that funny 'new Type', not typeless
'new *compute_size_for_me'.
Oops, 'malloc(N)' has a type, of course.

Yevgen

P.S. Is someone really not aware of this dead argument yet?
 
R

Richard Heathfield

(e-mail address removed) said:

And, of course, this "alternative" doesn't
accomplish any positive affect at all

Of course it does. It's shorter, neater, safer, more elegant.
(besides satisfying the neuroses
of some people in this group) versus the much simpler and safer

Actually it's longer, more complicated, less safe, and less elegant.
#define typeMalloc(type,qty) ((type *) malloc((qty)*sizeof(type)))

You can just compare it on safety, on cut and paste, simplicity, and
compatibility with C++. And the arguments against it, that are
repeated here over and over, are just blatantly false.

No, they're not false. When you learn some manners, let me know and I'll
go over them again for you.
 
Y

Yevgen Muntyan

Richard said:
(e-mail address removed) said:



Of course it does. It's shorter, neater, safer, more elegant.


Actually it's longer, more complicated, less safe, and less elegant.

int *something = myMalloc(1, something);

is surely shorter, neater, safer, more elegant than

int *something = myMalloc(int, 1);
No, they're not false. When you learn some manners, let me know and I'll
go over them again for you.

Hehe, this man insulted wrong person (no, I am not for insulting Keith
Thompson, I am against insulting *anyone*).

Yevgen
 
R

Richard Bos

Yevgen Muntyan said:
int *something = myMalloc(1, something);

is surely shorter, neater, safer, more elegant than

int *something = myMalloc(int, 1);

It's not shorter (in this case), but it's neater, more elegant, and
definitely safer, at least in the sense of "more easy to maintain".
Then again, you could ditch the needless macro and just write:

int *something = malloc(sizeof *something);

Neatest, safest, and most elegant.

Richard
 
Y

Yevgen Muntyan

Richard said:
It's not shorter (in this case), but it's neater, more elegant, and
definitely safer, at least in the sense of "more easy to maintain".

Yep, all of these are subjective (like spaces vs tabs) and highly
dependent on context.

something[0] = myMalloc(1, something[0]);

Neat.
Then again, you could ditch the needless macro and just write:

int *something = malloc(sizeof *something);

Well, point of introducing such a macro is a different story
(there are libraries which use such macros for various reasons,
though RH would probably say all those reasons are totally
bogus). But if you do have such a macro, which form is better?
Neatest, safest, and most elegant.

Safest - nope, neat and elegant - certainly, just not for everyone.

Best regards,
Yevgen
 
W

websnarf

Its none of those things (except in some cases it can be shorter, but
so is omitting the whole thing in the first place; short is usually
irrelevant if it does not decrease *vertical* screen space).
int *something = myMalloc(1, something);

is surely shorter, neater, safer,

It is not safer. First of all you are demanding that the programmer
play the part of the computer by doing this "automatic action" of
synchronizing the two. If you mismatch the variable name with the one
you are assigning (notice that has to be done manually), you get a
silent error. And what if someone writes this:

int *table[100], **p;

p = &table;
*p = myMalloc (1, *++p);
*++p = myMalloc (1, *p);

Figuring out what happens is like a puzzle and is not in the universe
of what I would call maintainable.
[...] more elegant than
int *something = myMalloc(int, 1);

If you mismatch the int, you get a compiler warning (in C++ you get an
error.) You can't pull crap to mess up this macro because the type
must be something you can cast to and take the size of. Every
mismatch scenario is detected.
 
Y

Yevgen Muntyan

Its none of those things (except in some cases it can be shorter, but
so is omitting the whole thing in the first place; short is usually
irrelevant if it does not decrease *vertical* screen space).
int *something = myMalloc(1, something);

is surely shorter, neater, safer,

It is not safer. First of all you are demanding that the programmer
play the part of the computer by doing this "automatic action" of
synchronizing the two. If you mismatch the variable name with the one
you are assigning (notice that has to be done manually), you get a
silent error. And what if someone writes this:

int *table[100], **p;

p = &table;
*p = myMalloc (1, *++p);
*++p = myMalloc (1, *p);

Figuring out what happens is like a puzzle and is not in the universe
of what I would call maintainable.
[...] more elegant than
int *something = myMalloc(int, 1);

If you mismatch the int, you get a compiler warning (in C++ you get an
error.) You can't pull crap to mess up this macro because the type
must be something you can cast to and take the size of. Every
mismatch scenario is detected.

I believe you replied to a wrong person ;)

Yevgen
 
R

Richard Bos

Old Wolf said:
You forgot the moon landing hoax..

And, more importantly, did the ISO C committee perhaps bury Jimmy Hoffa
under a stack of Standards?
What amazes me is that he (apparently) manages to write code that
other people use, and seems to work!

*Shrug* Microsoft manages to write code that other people use, and to
them it seems to work. To a mailadmin who has to clean up the debris
from botnets full of backdoored Windows boxlets, not so.

Richard
 
B

Bill Pursell

Every mismatch scenario is detected.

Forgive me for snipping so much context, and
also if I get this wrong, but I believe the
macro we're discussing is:

#define typeMalloc(type,qty) \
((type *) malloc((qty)*sizeof(type)))

I don't see how this detects the
mismatch here:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define typeMalloc(type,qty) \
((type *) malloc((qty)*sizeof(type)))

int
main(void)
{
void * x;
long long p[BUFSIZ];

x = typeMalloc(int, BUFSIZ);

memcpy( x, p, BUFSIZ * sizeof *p);
return EXIT_FAILURE;
}
 
Y

Yevgen Muntyan

Bill said:
Forgive me for snipping so much context,

That's maybe why you are asking what you are asking.
and
also if I get this wrong, but I believe the
macro we're discussing is:

#define typeMalloc(type,qty) \
((type *) malloc((qty)*sizeof(type)))

I don't see how this detects the
mismatch here:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define typeMalloc(type,qty) \
((type *) malloc((qty)*sizeof(type)))

int
main(void)
{
void * x;
long long p[BUFSIZ];

x = typeMalloc(int, BUFSIZ);

memcpy( x, p, BUFSIZ * sizeof *p);
return EXIT_FAILURE;
}

You can probably see how 'malloc (sizeof *x)' is better here?
Nobody ever claimed this typeMalloc() is foolproof. Point
is: it's no less safe (and probably is even safer) than kosher
comp.lang.c 'ptr = malloc(sizeof *ptr)' form.

Yevgen
 
B

Bill Pursell

<snip example where the macro doesn't catch the
type mismatch>
You can probably see how 'malloc (sizeof *x)' is better here?

Yes. That's my point. I think the macro
is silly.
Nobody ever claimed this typeMalloc() is foolproof.

Paul claimed: "Every mismatch scenario is detected."
But that isn't so. The macro is silly and gives
you nothing in return for needless obfuscation.
 
Y

Yevgen Muntyan

Bill said:
<snip example where the macro doesn't catch the
type mismatch>

Yes. That's my point. I think the macro
is silly.

If that's your point, look at your program again. Try to
compile it, for instance (with the "nice" 'malloc (sizeof *x)'
form).
Paul claimed: "Every mismatch scenario is detected."
But that isn't so.

You simply took it out the context. Do you always say "wrong"
if someone says "everything is fine here", regardless of what
it's about?
The macro is silly and gives
you nothing in return for needless obfuscation.

Well, if you think it's *silly* then it's impossible to
convince you in anything else. How about this: some people
use it successfully in some contexts, and it serves a good
purpose there? Those people are idiots, I guess, or not?

Yevgen
 
C

CBFalconer

Yevgen said:
Bill Pursell wrote:
.... snip ...


Well, if you think it's *silly* then it's impossible to
convince you in anything else. How about this: some people
use it successfully in some contexts, and it serves a good
purpose there? Those people are idiots, I guess, or not?

I can probably agree with the penultimate conclusion of the
ultimate sentence.
 
B

Bill Pursell

If that's your point, look at your program again. Try to
compile it, for instance (with the "nice" 'malloc (sizeof *x)'
form).

Okay, we'll change the line in question so
that it is of the desired form:
x = malloc( BUFSIZ * sizeof *p);
(x is a void *, so in this case the proper
form is to use the size of the object
that you are planning to have x point to).
And, conveniently, if you incorrectly write:
x = malloc( BUFSIZ * sizeof *x);
the compiler (gcc anyway) catches your error:
a.c:12: warning: invalid application of `sizeof' to a void type

You simply took it out the context. Do you always say "wrong"
if someone says "everything is fine here", regardless of what it's about?

No, I don't, but in this case you and Paul are, IMO,
wrong. Also, I didn't take it out of context: the
context is very clear, but the article to which
I was responding had removed the specific macro
before I got to it. I trimmed out irrelevant
context, and there was not much left. I
don't believe I have misrepresented anyone's
position. If I have done so, I am more
than willing to offer an apology.
Well, if you think it's *silly* then it's impossible to
convince you in anything else.

That's absurd. I often change my mind about
many things. I have read through this thread
and initially thought that the idea of
the macro might have some merit. In
considering the opinions represented here,
and considering my own experiences, I've
concluded that the macro doesn't provide
any benefit, but does obscure code
needlessly.

How about this: some people
use it successfully in some contexts, and it serves a good
purpose there? Those people are idiots, I guess, or not?

No, they are not idiots. I simply disagree
with them. I challenge Paul's claim that
the macro catches all type mismatches. And
I think the macro is silly. I do not think
that a person who uses the macro is silly, so
if you are offended because you thought I
implied that, well...stop being offended,
because I don't. I'm glad that you find
the macro helpful in many contexts, but
you have failed to convince me that its
alleged benefits outweigh its obfuscatory
nature. And you haven't yet shown a context
in which it is more useful than the natural
form.
 
Y

Yevgen Muntyan

Bill said:
Bill said:
Yevgen Muntyan wrote:
[snip]
How about this: some people
use it successfully in some contexts, and it serves a good
purpose there? Those people are idiots, I guess, or not?

No, they are not idiots. I simply disagree
with them.

Disagree in what? You mean they should not do that regardless
of why they use the macro, regardless of the context? One more
time: if one says "one must always use macro, macro is always
good", then he's wrong. But same thing is true about one who
says "the macro is never useful, one must not use it anywhere".
If someone finds "sizeof *p" worse than "sizeof (TheType)"
then it's indeed worse, and he might not do what you think
is "right" (and here we go: context, experience, and so on).
I challenge Paul's claim that
the macro catches all type mismatches.

He didn't claim that, you ripped it out the context. You said
it happened because someone else snipped appropriate context,
maybe. But if you didn't read the original Paul's post, then
you got second-hand information, but you still claim he claimed
what you're saying.
How can you think that a sane person claims something can
catch any type mismatches if we have void* anyway (and in worst
case brute force will break anything)?
And
I think the macro is silly. I do not think
that a person who uses the macro is silly, so
if you are offended because you thought I
implied that, well...stop being offended,
because I don't.

Nah, it's not just about me being stupid. It's about people who
call other's practices silly without *any* consideration.
You think "Why would I use it? It's silly!" and you are
right. But you are *saying* "I disagree *you* should use it,
it's silly". (You said you disagree with "those" people,
and I take it as you said they should not use such macros).
I'm glad that you find
the macro helpful in many contexts, but
you have failed to convince me that its
alleged benefits outweigh its obfuscatory
nature.

I didn't try to convince you, and I am not claiming it'd
be useful for *you* anywhere. But you are saying it's not
useful for anybody (e.g. me), which is silly.
Then, using such a macro in a standalone program which
uses standard C + this macro is indeed strange. But it
may not be the case. Such macros are provided by many
libraries, and if you use such a library you get the
macro for free. *Then* you get little better type-checking
than with raw malloc. *Then*, if you use the macro, you
use it a uniform way everywhere, not like your favorite
form which doesn't work in your example; the fact that
can be extremely important for some people. You know,
easier to read code, stuff like that. See, it's about
what one likes, not about what's "right".
If one grew up with "sizeof *p" thing (very C syntax, isn't
it), and encountered macros like that only in a newsgroup,
then I guess those macros look silly. Say, some people's
"no goto, ever" rule is totally stupid for me, but I wouldn't
say those people should or should not use goto. They shouldn't
*tell me* that I am wrong if I indeed use goto..
And you haven't yet shown a context
in which it is more useful than the natural
form.

Your example maybe?

x = malloc(sizeof *p);

is maintainable? I'd think it's a line of code which
strikes you immediately as wrong.

Anyway, just don't use such macros and be happy :)

Yevgen
 
B

Bill Pursell

Bill said:
Bill Pursell wrote:
Yevgen Muntyan wrote: [snip]
How about this: some people
use it successfully in some contexts, and it serves a good
purpose there? Those people are idiots, I guess, or not?
No, they are not idiots. I simply disagree
with them.

Disagree in what? You mean they should not do that regardless
of why they use the macro, regardless of the context?

I have never said that I disagree with
the claim the some people use it
successfully in some contexts. I do
disagree that any such context has
been given as an example in this
thread. I am not trying to enforce
my belief about the macro on anyone.
I originally joined this thread because
I had a simple example that I believe
demonstrates that the macro is NOT
robust, and I wanted to get the viewpoint
on that example from someone with a
differing opinion. I did this primarily
because I am giving the macro consideration,
a point which you seem to be missing.


One more
time: if one says "one must always use macro, macro is always
good", then he's wrong. But same thing is true about one who
says "the macro is never useful, one must not use it anywhere".

I said "the macro is silly". Don't put words
in my mouth. I didn't claim it is never
useful, nor do I claim that. I do think
it's silly, and I will probably never use
it myself. Nowhere have I claimed that
no one should ever use it.
If someone finds "sizeof *p" worse than "sizeof (TheType)"
then it's indeed worse, and he might not do what you think
is "right" (and here we go: context, experience, and so on).

I disagree. Someone might find readable
names worse than short names and might
like long functions and that person might
like to write 1000 line functions that begin
with: "int i,ii,j,jj,k,kk,ll,mm,m,n;".
But {his,her} perspective is amatuerish,
and the short functions with readable
names is not "indeed worse" simply because
of that person's perspective.
He didn't claim that, you ripped it out the context.

Yes, he did. I've gone back and looked at the
full context, and it certainly looks to me
that that is exactly what he claimed.


Nah, it's not just about me being stupid. It's about people who
call other's practices silly without *any* consideration.

Stop. Why do you continue to think that I've
given the macro no consideration? The entire
reason I joined this thread was precisely
because I was considering it. I tried
it out, found it to have a serious flaw,
and pretty much forgot about it. Then
I saw Paul's claim that the macro
catches all mismatches (and in going
back to look at the full context, it
still appears to me that that is exactly
what he claimed) and I posted an example
which I believe demonstrates a type
mismatch that the macro doesn't catch.
You think "Why would I use it? It's silly!" and you are
right. But you are *saying* "I disagree *you* should use it,
it's silly".

Again, I have not said that I think no one should
use it. Have I
written a plugin to your VCS which will
reject any code using such a macro? Have
I made a request to any compiler vendors
that they modify their preprocessors to
reject such a macro? Have I ever once said,
"No one should use it."? Have I ever said
"No one should use anything that I think
is silly"? No. I haven't, and I don't
think that. I do think this macro is
silly, though.
(You said you disagree with "those" people,
and I take it as you said they should not use such macros).

Well, you take it wrong. I'm not making
any claims about people at all. (Unlike
you, who seem to think that I'm closed
minded and unwilling to grow). I think
this macro is silly. I don't think
anything about the people who use it.
Perhaps a few more examples would serve.
I think it's silly that "int * x,y;"
declares a pointer and an integer rather
than 2 pointers. I think it's silly
that == has higher precedence that &.
I do not think that K&R are silly.
Quite the contrary.
I didn't try to convince you, and I am not claiming it'd
be useful for *you* anywhere. But you are saying it's not
useful for anybody (e.g. me), which is silly.

For (at least) the 3rd time, I am not saying
it's not useful for anybody. I am saying
that I don't see the use.
Then, using such a macro in a standalone program which
uses standard C + this macro is indeed strange. But it
may not be the case. Such macros are provided by many
libraries, and if you use such a library you get the
macro for free. *Then* you get little better type-checking
than with raw malloc.

And here I go again, giving the macro more
consideration. And here's why I think it's
silly: if you have a large code base in
which you've used this macro, and then
discover that you need to change a type
from int to long, you now get nice
compiler warning about type mismatches
in many places, and you have to go
make changes. If you have used
the malloc(sizeof *x) model, then you
don't get warnings and you don't
need to change the code base (because
the code still works).

*Then*, if you use the macro, you
use it a uniform way everywhere, not like your favorite
form which doesn't work in your example; the fact that
can be extremely important for some people. You know,
easier to read code, stuff like that.


Yes. I'm one of those people to whom it's
extremely important. I like clean, readable,
maintainable, robust, aesthetically appealing
code. My favorite form works perfectly correctly
in this example. It seems to me that
the problem here is your unwillingness to
give the standard form due consideration.


See, it's about
what one likes, not about what's "right".

Sometimes, what one likes is clearly not right.
That's not the case here, but there are definitely
times when there is a right way to do things.

If one grew up with "sizeof *p" thing (very C syntax, isn't
it), and encountered macros like that only in a newsgroup,
then I guess those macros look silly.

Pay attention. I'm a novice. I first
encountered sizeof *p within the last
12 months. Prior to that, I thought
that "sizeof(type)" was the only valid
format. I saw sizeof *p on this newsgroup
and gave it some consideration and realized
that it is "the right thing" (tm). I
saw this macro, gave it consideration,
and rejected it because I believe it's
bogus.

Say, some people's
"no goto, ever" rule is totally stupid for me, but I wouldn't
say those people should or should not use goto.

We're totally in agreement. I think goto is
a powerful statement and I think that the claim
that it should be completely avoided is silly.

They shouldn't
*tell me* that I am wrong if I indeed use goto..

Just to be clear, in case you missed it: I don't
think that you are wrong if you use this macro.
I do think that you are missing out on a
better model.

Your example maybe?

x = malloc(sizeof *p);

is maintainable? I'd think it's a line of code which
strikes you immediately as wrong.

Yes, it does. And if I saw it, I would
immediately check the declaration of x,
realize it was void *, and know that
it is intended to point at an object
of type *p. Not only that it will point
at an object of the same type as *p, but
pretty likely it will either point directly
to an entry in p, or it will be used
to hold copies of items in p. On the
other hand, if I see:

int *p;
int *q;
void *x;
....
x = typeMalloc( int, N );

I don't know if x is related to p or q.
 
W

websnarf

Every mismatch scenario is detected.

Forgive me for snipping so much context, and
also if I get this wrong, but I believe the
macro we're discussing is:

#define typeMalloc(type,qty) \
((type *) malloc((qty)*sizeof(type)))

I don't see how this detects the
mismatch here:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define typeMalloc(type,qty) \
((type *) malloc((qty)*sizeof(type)))

int
main(void)
{
void * x;
long long p[BUFSIZ];

x = typeMalloc(int, BUFSIZ);

memcpy( x, p, BUFSIZ * sizeof *p);
return EXIT_FAILURE;

}

Ok, obviously nothing can be done about void * pointers, but either
way, this is actually not a mismatch of allocation (since void * can
accept any allocation), its a mismatch on the memcpy, which is a
different thing.
 
Y

Yevgen Muntyan

Bill said:
Bill said:
On Mar 8, 10:07 pm, Yevgen Muntyan <[email protected]>
wrote:
Bill Pursell wrote:
Yevgen Muntyan wrote: [snip]
How about this: some people
use it successfully in some contexts, and it serves a good
purpose there? Those people are idiots, I guess, or not?
No, they are not idiots. I simply disagree
with them.
Disagree in what? You mean they should not do that regardless
of why they use the macro, regardless of the context?

I have never said that I disagree with
the claim the some people use it
successfully in some contexts. I do
disagree that any such context has
been given as an example in this
thread.

I guess this is the problem: you said "Disagree with them", disagree
with those people. I understood it the way I did, since the people who
use that macro often don't even read comp.lang.c, they have nothing to
do with this thread, and disagreement with them can mean only one thing:
they are wrong when they think the macro is good for them. Anyway,
it's not what you wanted to say, as you said now. I apologize for
misunderstanding, you probably are just not aware of this "sizeof *p vs
non-natural form" issue. It's hot.

As to context in this thread, it can't be provided since it's
totally off-topic. All we talk about here is toy programs or programs
written by couple of regulars. And indeed, it's hard to provide
a completely standard C example (it would need to be short, right?)
where introducing such a macro wouldn't look as mere obfuscating.
You can look at gnome (the desktop thing) code base,
it's full of macros like that. People think it's type-safe (not
totally safe, mind you).

....
Just to be clear, in case you missed it: I don't
think that you are wrong if you use this macro.
I do think that you are missing out on a
better model.

We agree (to disagree) then. But I don't miss a better model:
I believe using malloc(anything) is more dangerous than
(TheNeededType*)malloc(anything); hypothetical inconvenience
when changing some types (we often do it, don't we)
is less expensive than type mismatch errors. (Type*)malloc(..)
always have the appropriate type, and it's safe to assign
it to anything except void* pointers, unlike the 'better'
form which simply can't be used everywhere, and hence can't be
said to be as safe. 'void *foo = ..' is a separate issue
unrelated to malloc().

Best regards,
Yevgen
 

Ask a Question

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

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

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top