In article <11**********************@o13g2000cwo.googlegroups .com>
vb@gmail.com <vb*****@gmail.com> wrote:
I am a newbie in C and i want to know what all pointer conversions are
"legal" according to ANSI C standard. For Example, int* to char*,
some_struct* to char* and so on ..
According to me, since any pointer can be cast to void* and void * can
be cast to any other pointer so this implies that any pointer can be
cast to any other pointer. Is that so?
As others have noted, it is not so. The reasoning here has a
flaw.
You are correct in that any "data pointer" (but not function pointer)
can be converted to "void *" and back without losing any important
information. But from this, you conclude that any (data) pointer
can be converted to any other data pointer. Why?
Consider, if you will, "int" and "double" as a similar example.
Suppose that "int" ranges from -32768 to +32767 (as it does on most
16-bit CPUs) or even -2147483648 to +2147483647 (as it does on most
32-bit CPUs), while "double" is a typical 8-byte IEEE double that
has 53 "mantissa" bits and thus can represent all integers up to
+/- 9007199254740992 (remember that IEEE floating point uses
sign-and-magnitude representation, so unlike two's complement,
the range is symmetric).
Now imagine that "double" is analagous to both "void *" and
"char *" ("byte pointers"), while "int" is the analagous to
"int *" and other "word pointers". You can always take any
word pointer and store it in a byte pointer, just as you can
always take an ordinary "int" value and store it in a "double".
But there are "double" values that you cannot store in an
"int", such as 3.5. If you store 3.5 in an int, the 0.5
part "falls off the end", and when you convert it back to
double, you get 3.0.
The same actually happens (on some real machines) when you use byte
pointers and word pointers. Word pointers only ever point to "whole
words": word 0, word 1, word 2, and so on. But each "whole word"
is made up of at least 2 (and as many as 8, on the Cray) "bytes"
-- so a byte pointer needs one, two, or even three more bits than
a word pointer. When you convert from one to the other, the extra
bits are added or removed as needed. If the bits in a byte pointer
were not zero, removing those bits discards "useful information",
and when you convert the word pointer back to a byte pointer, the
byte offset within the word is gone: the pointer's value has changed.
Less concretely (but perhaps easier to remember): Think of pointer
values as water, and pointer objects (of various types, like
"int *" and "struct foo *") as cups, glasses, mugs, beer-steins,
and the like. "void *" is a Really Big Bucket, into which you can
pour *any* container of pointer. You can then pour the contents
back into the original container, because the Big Bucket will only
be as full as the original container was. But if you pour a beer
stein ("char *") into the bucket ("void *"), then pour the bucket
into a shot-glass ("int *"), some of the beer will slop out.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it
http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.