5 ms·
Why was he complaining about the stack pointer first? Isn't this line: st1 = (void *)malloc(5000) + 5000; completely invalid too? You can't (I think it's un
by afhof 16y ago
Why was he complaining about the stack pointer first? Isn't this line:
st1 = (void *)malloc(5000) + 5000;
completely invalid too? You can't (I think it's undefined) increment a void pointer.
- tptacek 16y agoIt may be undefined, but gcc accepts it without warning under -Wall and does exactly what you'd expect. Note that (a) casting malloc's return is evil, (b) casting malloc to void* is silly since it's declared returning void* already, and (c) casting malloc to void* so it can be received as a char* is also pretty goofy.
- NickPollard 16y agoThis might be a stupid question, but what are you meant to do if not cast malloc's return? My C is a bit rusty, but how else are you meant to allocate data of different types on the heap?
- scott_s 16y agoC allows implict casting of void* to any other kind of pointer. Hence, you never need to cast the return from a malloc if you're storing it in a pointer. C++, however, does not allow this. So, if for some reason you're calling malloc rather than new in C++, you need to cast.
- sanderjd 16y agoYou are not the poster who said "casting malloc's return is evil", so perhaps you don't agree with that statement, but I don't see how either of the points you make lead to the conclusion that it is "evil". You say that since void* is implicitly cast to all pointer types, you never need to explicitly cast it, but why would that make an explicit cast evil?
- tptacek 16y agoThere's nothing wrong with returning void. There is something wrong with casting void. First, as someone else already pointed out, it can lead to an LP64 bug if you miss the declaration for malloc(), since int and caddr_t are not necessarily the same thing. But the bigger problem is that casting to void* basically tells the compiler "stop all further type checking". That's not a big deal if the token "malloc" on that line never changes, but, in real codebases, allocators get changed all the time. If you change from foo_alloc() to bar_alloc(), the compiler will rightly freak out when you try to assign a foo* to a bar. But that (void) construction explicitly prevents that check from occurring, thus turning what should be a compile-time error into a runtime error.
- fintler 16y agoYep, it's basically undefined because a void type has no known size to do pointer arithmetic with.
- koenigdavidmj 16y agoGCC whines and moans, but treats it like a pointer to char.
- tptacek 16y agoGCC does not whine and moan about this, even if you ask for it to.
- koenigdavidmj 16y agoOh, right. (Forgot that my `gcc` is a shell script that adds a bunch of `-W` options.) You can ask for it with -Wpointer-arith.
- scdlbx 16y agoActually, since st1 is a char* and the sizeof char is 1, that is a valid declaration. It just probably isn't doing what the writer expects. It allocates 5000 bytes and then moves the pointer to point at the very last byte. edit: Though free()ing it would not work so well until you move the pointer back to the beginning of the 5000 bytes.
- azim 16y agoI think that's what the writer expected. On x86 the stack starts at a high address and grows downward to a lower address.
- mfukar 16y agoYes, arithmetic on void * is disallowed. However, gcc accepts it as an extension: http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html#SEC78 http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html#SEC78