Pointer conversions and Data types conversions

V

vb

Hi all,
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?
 
P

pete

Hi all,
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?

No.
A pointer can be converted to a pointer to void,
and converted back to the original type and value.
Little else is guaranteed about conversions to pointer to void.
 
C

Cong Wang

Hi all,
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?
Every pointer is an address of memory.Most of the pointers are integers
and a few are not (This has been mentioned in comp.lang.c.).The kind of
pointer will tell the compiler how many bytes and what type of the data
it points to.So we can cast a pointer from one type to another,but it
is not safe and maybe you get some warnings!You should be careful
enough to use a 'void*' pointer,though it is very useful.
 
R

Richard Heathfield

Hi all,
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

Casts are explicit conversions, and actually a side-issue here. What you are
really talking about is conversions in general, not necessarily explicit
conversions.

In fact, the guarantee in the Standard amounts to this: that, for any object
type T, the following transformation:

T *tp = &SomeObjectOrOtherOfTypeT;
void *vp = tp;
T *ntp = vp;

does not lose information. That is, after this code is executed, tp and ntp
will point to the same object.

If you are silly enough to do this:

T *tp = &SomeTOrOther;
void *vp = tp;
U *up = vp;

then you are skating on much thinner ice. For example, pointers-to-T and
pointers-to-U might have different numbers of significant bits.

so this implies that any pointer can be
cast to any other pointer. Is that so?

Yes, there is no limit to the thinness of the ice on which you can skate.
Sooner or later, though, the surface will crack, and in you'll go. Wise men
observe the signs, rather than take the dunking.
 
R

Richard Heathfield

Cong said:
So we can cast a pointer from one type to another,but it
is not safe and maybe you get some warnings!

Unfortunately, the cast is more likely to /remove/ some warnings, which is
why many people are silly enough to use it so often.
 
R

Richard Bos

pete said:
No.
A pointer can be converted to a pointer to void,
and converted back to the original type and value.
Little else is guaranteed about conversions to pointer to void.

This is true for object pointers (and pointers to incomplete types), not
for function pointers.

Pointers to types not qualified const etc. may be converted to pointers
to that same type with such qualifiers, and the result is a usable
pointer to the same object or function as the original.
Null pointer constants may be converted to any pointer type, and will
result in a null pointer; and null pointers may be converted to any
other kind of null pointer.
Integers may be converted to pointers, but not usefully unless your
implementation specifies this beyond the Standard (some do). Ditto vice
versa, and if the result can't be represented in the target type, you
have outright UB.
Object and incomplete-type pointers may be converted to one another, but
not usefully (the result is not required to be well-aligned, and if not,
the result is UB), except for:
Object pointers may be converted to pointer to (any kind of) char, and
the result points at the first byte of the object pointed to.
Function pointers may be converted to any function pointer type, and
remain their original value; you cannot reliably call a function through
a pointer of the wrong type, but you can convert it back to the right
type and get a callable pointer.

Richard
 
L

Lawrence Kirby

Every pointer is an address of memory.

Not necessarily. For example a null pointer need not in any sense
correspond to a memory address.
Most of the pointers are integers
and a few are not (This has been mentioned in comp.lang.c.).

There is no sense in which C considers a pointer to be an integer. C does
allow casting between pointer and integer types but the language doesn't
define the result in most cases, except that a null pointer constant
(which may be an integer) converted to a pointer type gives a null
pointer. Thinking of pointers as integers isn't really useful and can
lead to dangerous/wrong assumptions.
The kind of
pointer will tell the compiler how many bytes and what type of the data
it points to.

A pointer to object type indicates the size of object being pointed at, a
pointer to incomplete type (e.g. void *, pointer to an incomplete
structure, union or array typeor a pointer to a function doesn't.
So we can cast a pointer from one type to another,but it
is not safe and maybe you get some warnings!You should be careful
enough to use a 'void*' pointer,though it is very useful.

Casts very often get rid of warnings which is what makes them so
dangerous. Just because the compiler doesn't warn doesn't mean the code is
correct or even well defined.

Lawrence
 
C

Chris Torek

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.
 
K

Keith Thompson

Never do such things in real code. you will do a segfault in 90% of
cases.

Context, dammit!

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.
 
J

Jasen Betts

Hi all,
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?

You can do the cast, but there's no guarantee that the converted pointer will
work unless it originated from the same type.

S if you start with int* and convert it to char* or void* and then back to
int* that's legal, but if you start with char* and convert it to int*
and try to use it some hardwarw will baulk unless it's word aligned
(for whatever word width the architecture uses)


Bye.
Jasen
 

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

Staff online

Members online

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top