Maybe, but if your that asleep maybe you would cast
to the wrong type.
Maybe, but if your that asleep maybe you would cast
to the wrong type.
If you're so asleep as to cast it to the wrong type then you're not aware of the type(amount) of memory you're allocating, so cast or no cast you're in trouble.
Joe
malloc returns a pointer to some memory (if successful). How you choose to interpret this memory depends on the type of the pointer to which this value is assigned. The cast is irrelevant if you are using a construct like the following, which will always be correct.Originally posted by JoeSixpack
A possible benefit of casting would be that you ensure that you are using the correct pointer type. If you want a block of ints, casting the return type ensures that you can only assign the memory location to an int pointer (or that you should at least get some kind of warning, depending on your compiler).This way I can be completely asleep and not even care about the type of *t or how big it might be -- the compiler will handle that and at runtime it will kindly ask for room for 10. So why bother getting a warning about an incorrect cast -- since that is the only thing that would be incorrect if you used N * sizeof(*t) -- and then spending your time maintaining this unnecessary code? It is already correct without it.Code:mytype *t = malloc(10 * sizeof(*t));
This is correct (in theory, if not syntax), but doesn't properly address my point. If you want x mytypes, then you can ask for x mytypes and be certain that you're getting x mtypes (as oposed to x t's) and that you're assigning the address the correct type of pointer if a cast is used. The type information may not always be present in the expression using your method. Further on in your code you may have -The cast is irrelevant if you are using a construct like the following, which will always be correct.
code:--------------------------------------------------------------------------------mytype *t = malloc(10 * sizeof(*t));--------------------------------------------------------------------------------
.
t = malloc(20 * sizeof(t));
Did you really want 20 t's? t is just a variable name. It is possible that due to an oversight you believed t was of type mytype2 and not mytype. If you want 20 mytype2's, you can guarantee that if there's room enough and t is a pointer to mytype2 then this'll get them if it doesn't issue an error or warning -
t = (mytype2*)malloc(20 * sizeof(mytype2));
Joe
I would prefer to ask for space for objects of the same type as the pointer, and not have to worry about what the type is specifically.Originally posted by JoeSixpack
This is correct (in theory, if not syntax), but doesn't properly address my point. If you want x mytypes, then you can ask for x mytypes and be certain that you're getting x mtypes (as oposed to x t's)So the following is "fixed" with the cast?[...] and that you're assigning the address the correct type of pointer if a cast is used.Once I replace sizeof(type) with sizeof(object of same type as pointer), then I don't "need" the cast that helps hide the above bug.Code:int *t = (int*)malloc(N * sizeof(int*));Continuing...Code:anytype *t = malloc(N * sizeof(*t));How does a variable lose its type?[...] The type information may not always be present in the expression using your method.Actually, no. I didn't want space for 20 pointers; I wanted space for 20 objects.[...] Further on in your code you may have -
t = malloc(20 * sizeof(t));
Did you really want 20 t's?No, t is a pointer of some type. And sizeof(*t) is -- ahem -- the size of the object to which it points, whatever type that may be.[...] t is just a variable name.Actually I didn't care what the underlying type of t was because it no longer mattered. Whatever type it is, I'm asking for space for 20 of them. Because I didn't ask for space for a number of a presumed type -- I instead asked for space for a number of objects of the same type as the pointer -- this problem does not arise.[...] It is possible that due to an oversight you believed t was of type mytype2 and not mytype.Then you change t to anothertype and you have two more places to edit. I don't.If you want 20 mytype2's, you can guarantee that if there's room enough and t is a pointer to mytype2 then this'll get them if it doesn't issue an error or warning -
t = (mytype2*)malloc(20 * sizeof(mytype2));
I'm sorry. I've been down this road and back again several times. I have yet to see any justifyable advantage to casting. The only thing mentioned lately is for use with pre-ANSI compilers. Frankly I'd rather have the warnings pop up to let me know that I'm using an ancient compiler.
Yeah, what the hell does it matter what you actually need?I would prefer to ask for space for objects of the same type as the pointer, and not have to worry about what the type is specifically.
But once again you're explicitly including the type in the expression. Do you declare a new pointer everytime you need some memory? If not how are you sure you've always got the correct type?Once I replace sizeof(type) with sizeof(object of same type as pointer), then I don't "need" the cast that helps hide the above bug.
Where did I say the variable loses its type?How does a variable lose its type?
int i = 0;
//some code
i=10;
what is i?
It hasn't lost it's type. But the programmer is using a variable called i without explicitly using the type.
This is true.Actually, no. I didn't want space for 20 pointers; I wanted space for 20 objects.
and this. I'm sorry.No, t is a pointer of some type. And sizeof(*t) is -- ahem -- the size of the object to which it points, whatever type that may be.
WTF?? Of course you care what the underlying type is. If you want space for 20 int's, you want space for 20 int's. I can't see how what you've described could be anymore ass-backwards. Let's take some pointer type and hope the data fits.Actually I didn't care what the underlying type of t was because it no longer mattered. Whatever type it is, I'm asking for space for 20 of them. Because I didn't ask for space for a number of a presumed type -- I instead asked for space for a number of objects of the same type as the pointer -- this problem does not arise.
How? You've got at least one place to edit by changing your type somewhere. I'd only have one if I used a macro.Then you change t to anothertype and you have two more places to edit. I don't.
Joe
Regarding the usage of malloc, I prefer:
TYPE *ptr;
ptr = malloc( sizeof( TYPE ) * NUMBER_TO_ALLOCATE );
There is no benefit I can see to ever casting, unless you are implicitly converting from one type to another. In malloc's case, there is no reason to ever cast that I can envision. The return type of malloc is to a continuous block of N bytes where N is:
sizeof( TYPE ) * NUMBER_TO_ALLOCATE
As such, it really doesn't matter what it's cast into, the cast is a moot point. Once a pointer is pointing at some block of memory, it could care less what type it was cast to when it was originally set to the address.
Setting a pointer to point to an address does not change its type. As such, there is nothing that casting pointers from one type to the next provides, other than preventing your compiler from yelling at you. Example:
char *c;
int *i;
float *f;
f = (float*) i = (int*) c;
This will (I believe, haven't bothered trying it) prevent your compiler from *****ing at you, but the end result is irrelevent.
In the end, they all point to the same spot in memory, and in the end, when you increment any of them, they only increment by N bytes, where N is the size of each variable.
So the end result is, it doesn't matter what you cast a pointer to, it will still be its own type, and nothing you can do will change that, unless you implicitly force cast it in incrementation:
((float*)c)++;
Quzah.
Hope is the first step on the road to disappointment.
The cast (if used) is you telling the compiler that this is what you meant.As such, it really doesn't matter what it's cast into, the cast is a moot point.
No, it's not meant to. It's so the compiler can give an error/warning. If you assign a block of memory to a different type of pointer than you had intended it may not have the desired affect.Setting a pointer to point to an address does not change its type
The problem isn't with the allocated memory, as casting isn't going to help if you balls up here. But with how this memory is manipulated.
Exactly, but if you want a block of memory that can be manipulated in 1 byte regions, but allocate it to a pointer that increments/decrements in 4 byte regions then the pointer isn't going to care that you've made a mistake. However, casting the return value of malloc allows your compiler to provide a warning to this affect.Once a pointer is pointing at some block of memory, it could care less what type it was cast to when it was originally set to the address.
If you want a block of memory that you can manipluate in N-1 byte sections then either you're going to have to ensure that the address is assigned to a pointer that can increment by N-1 bytes (which you can be sure of if you cast), or by casting the pointer each time it's used (in which case why are you using the wrong type in the first place).In the end, they all point to the same spot in memory, and in the end, when you increment any of them, they only increment by N bytes, where N is the size of each variable.
The point in casting in this instance isn't to force the pointer to be something it isn't; but to enable the compiler to provide an error/warning.So the end result is, it doesn't matter what you cast a pointer to, it will still be its own type, and nothing you can do will change that, unless you implicitly force cast it in incrementation
An example -
Code:#include<stdlib.h> int main(void) { char *c; double *d; //lots of code //Lets say I want 20 integers //this is wrong because I've //assigned it to a character pointer //even though I have the correct amount //of memory c = malloc(20*sizeof(int)); //this is wrong because I've //made an error in assuming that //d is a pointer to an integer d = malloc(20*sizeof(*d)); //A cast indicating my intentions //on either of the previous 2 would //have brought the error to my attention //with a compiler error/warning //As they stand this program is //buggy as hell return(0); }
Joe
???Originally posted by JoeSixpack
Yeah, what the hell does it matter what you actually need?Uh, no. The type is implicity present in the pointer variable. (Or do you see an explicit type as the operand of my sizeof?) And no.Originally posted by JoeSixpack
But once again you're explicitly including the type in the expression. Do you declare a new pointer everytime you need some memory?*t has a type.Originally posted by JoeSixpack
If not how are you sure you've always got the correct type?...as previously quoted.Originally posted by JoeSixpack
Where did I say the variable loses its type?Originally posted by JoeSixpack
The type information may not always be present in the expression using your method.The other two places being the cast and the operand to sizeof. I'd have only the pointer declaration (even if I didn't use a macro): the pointer variable declaration.Originally posted by JoeSixpack
WTF?? Of course you care what the underlying type is. If you want space for 20 int's, you want space for 20 int's. I can't see how what you've described could be anymore ass-backwards. Let's take some pointer type and hope the data fits.How? You've got at least one place to edit by changing your type somewhere. I'd only have one if I used a macro.Originally posted by Dave_Sinkula
Then you change t to anothertype and you have two more places to edit. I don't.
If t is an int pointer, then *t is an int. And if t is a pointer to some other type, then *t is whatever type that is. Or is that ass-backwards?
You're missing the point. The compiler doesn't CARE what you cast to. It has no effect. There is no point what so ever in casting malloc! It provides NOTHING to your code. It is worthless. It doesn't MATTER what you cast to, because you are casting a VOID POINTER. Void pointers, as far as your compiler is concerned, can go to ANYTHING, and there is absolutely no point what so ever in casting the return.Originally posted by JoeSixpack
The cast (if used) is you telling the compiler that this is what you meant.
You're just asking your compiler to yell at you by possibly casting it to the wrong type. There is no benifit what so ever in casting a void pointer. Period. Ever. End of story.
We're talking about void pointers. There is no reason to ever cast a void pointer. Your compiler will not complain about it, because it is impossible to cast a void pointer to the wrong type. Ever.Originally posted by JoeSixpack
No, it's not meant to. It's so the compiler can give an error/warning. If you assign a block of memory to a different type of pointer than you had intended it may not have the desired affect.
The only reason you could ever possible get this wrong is if you typed the single malloc line wrong:
char * c = malloc( sizeof(float) * 100 );
And even then, it still won't care. The only way it would care, would be if you cast it implicitly. Why on earth would you?
char * c = (float*) malloc( sizeof( float ) * 100 );
And that's absurd. Why on earth would you ever do that? There is no point in EVER casting void pointers. Period.
Yes, but how in the hell would this ever happen? You would have to be incredibly stupid and drunk to have this happen. In this case, casting is not going to save you. If you are stupid enough to malloc this incorrectly in the first place, then the chances are you're going to have screwed up your cast anyway, so there again is no benifit.Originally posted by JoeSixpack
Exactly, but if you want a block of memory that can be manipulated in 1 byte regions, but allocate it to a pointer that increments/decrements in 4 byte regions then the pointer isn't going to care that you've made a mistake. However, casting the return value of malloc allows your compiler to provide a warning to this affect.
Your argument is absurd, as is your example. I cannot envision this ever possibly happening. By all means, feel free to cast, but there is absolutely no point in ever doing so. Your example is incredibly far fetched. You're basicly saying "Hey, forget that you just declared a variable, and pretend that you think it's some other type!"
Quzah.
Hope is the first step on the road to disappointment.
There is one interesting point here that is almost illustrated.
I get no compiler warning when I try to assign a variable of one type the value of another type for which there is an implicit type conversion. Lint will pick this out, but the compiler (with the options I've selected) lets it fly. That is to say, the compiler issues no diagnostic for the following.Originally posted by JoeSixpack [and snippage by Dave_Sinkula]
An example -
Code:#include<stdlib.h> int main(void) { double *d; //lots of code //Lets say I want 20 integers //this is wrong because I've //made an error in assuming that //d is a pointer to an integer d = malloc(20*sizeof(*d)); return(0); }Hmmm. I still despise casts. When not used for an actual conversion (like truncation of an int to a char), they are simply lies. But this is an issue I will have to consider. (At least the memory allocation is correct, although it should be free'd so as not to be rude.)Code:int x = 5.0;
This isn't what I'm talking about at all. As I'm getting tired of repeating myself I'll refer you to my example posted above.You're missing the point. The compiler doesn't CARE what you cast to. It has no effect. There is no point what so ever in casting malloc! It provides NOTHING to your code. It is worthless. It doesn't MATTER what you cast to, because you are casting a VOID POINTER. Void pointers, as far as your compiler is concerned, can go to ANYTHING, and there is absolutely no point what so ever in casting the return.
Ok, explain how there would be no benefit in casting in my example.You're just asking your compiler to yell at you by possibly casting it to the wrong type. There is no benifit what so ever in casting a void pointer. Period. Ever. End of story.
Where have I stated anything different? This is not what I'm talking about.Your compiler will not complain about it, because it is impossible to cast a void pointer to the wrong type. Ever.
Hooray, at least I seem to have gotten through. It may be absurd, but my example shows a situation where casting would be beneficial.Your argument is absurd, as is your example. I cannot envision this ever possibly happening.
If you cannot show me how casting would not highlight the errors (and therefore help in the fixing of those errors) in my example posted above then my point stands no matter how absurd you believe it to be. End of story.
Joe
int* p;
p=(char*)malloc(100);
so what? Compiler says: failure!
But what is the benefit?
It's a false sense of security:
p=(int*)malloc(100);
The compiler don't say anything - but it's also wrong...
What does it help?
If you don't know which type p is, you are completly lost.
I don't want to discuss such things. Go and read K&R. Do they cast?? Or look for other gurus! They will tell you all the same.
The only reason why one casts a void* is to keep compability with C++, there is no other reason.
Hope you don't mind my bad english, I'm Austrian!
Yawn. The benefit is that if you use the cast to indicate you're expecting the block of memory to be pointed to by a character pointer and if you foolishly point something else at it the compiler will let you know. Is this really that hard to comprehend?But what is the benefit?
It's not wrong for the reason posted above though. It's not supposed to help when you try and allocate the incorrect amount of memory. Does this mean it's not useful in your first example?It's a false sense of security:
p=(int*)malloc(100);
The compiler don't say anything - but it's also wrong...
What does it help?
Why bother having the compiler do any type checking at all then?If you don't know which type p is, you are completly lost.
Can you not tell me why? I'm not necessarily stating that you should cast the return value of malloc. Just countering the point that it is of no benefit. Your last point is a non-argument.I don't want to discuss such things. Go and read K&R. Do they cast?? Or look for other gurus! They will tell you all the same.
Joe
I fully understand your point, but it just doesn't help to cast malloc(). Joe, if you really think that casting can help in a certain situation, then think about this :Originally posted by JoeSixpack
Yawn. The benefit is that if you use the cast to indicate you're expecting the block of memory to be pointed to by a character pointer and if you foolishly point something else at it the compiler will let you know. Is this really that hard to comprehend?
You're 500 lines into your program and you need to allocate some memory, here's what you see,
You can't see the decalaration of temp but you know it's type. So if you happen to pass the wrong type to sizeof(), then what's the point in casting the return of malloc()?Code://.. temp = malloc ( sizeof ( type ) * NUM_OF_ELEMENTS ); //..
Yeah you could argue that you can just scroll up to temp's declaration, but then you'd never pass the wrong type to sizeof(), so what's your argument?
You're f'ed both ways!
Casting doesn't help, in any way, IMO.
Is your compiler gonna stop you from doing this :
Nope, I didn't think so.Code://.. int *iPtr; iPtr = malloc ( sizeof ( char ) * NUM_OF_ELEMENTS); //..
But then you still have to check that the amount of memory that you're allocating is correct. So if you have to check both, why not leave the cast, and just check the size.Originally posted by JoeSixpack (Worded differently)
Casting a malloc() return in C can only be beneficial when trying to assign mismatched pointers.
Thus, less checking, less typing. So c'mon how can casting a malloc() return be beneficial?
And the beat goes ooooooooon! Ladadadadee, Ladadadadaa.