void *

M

Mark

Hello,

consider this piece:

int x;
printf("address of x %p\n", &x); /* 1*/
printf("address of x %p\n", (void *)&x); /* 2 */

Are these expressions equivalent?

gcc-4.1 on my system sensibly complains on the first 'printf', but both
outputs are the same. I do understand that if printf()'s %p specifier
requires its argument to be a pointer to void, then the behavior of the (1)
is undefined ? On the other hand, a pointer can be converted to (void *).

PS. I tend to use the second form.
 
S

Shao Miller

Mark said:
Hello,

consider this piece:

int x;
printf("address of x %p\n", &x); /* 1*/
printf("address of x %p\n", (void *)&x); /* 2 */

Are these expressions equivalent?

gcc-4.1 on my system sensibly complains on the first 'printf', but both
outputs are the same. I do understand that if printf()'s %p specifier
requires its argument to be a pointer to void, then the behavior of the
(1) is undefined ? On the other hand, a pointer can be converted to
(void *).

PS. I tend to use the second form.

The alignment and representation for an 'int *' need not be the same as
for a 'void *'. An 'int *' could be 42 bytes, whereas a 'void *' could
be 3 bytes. 'printf' is expecting a 'void *' for the "%p" formatter.

And yes, an 'int *' can be converted to a 'void *', either implicitly or
explicitly. In your 'printf' #2, you accomplish an explicit conversion
via a cast.
 
M

Malcolm McLean

int x;
printf("address of x %p\n",  &x);    /* 1*/
printf("address of x %p\n",  (void *)&x);    /* 2 */

Are these expressions equivalent?
A few systems can only address 32-bit words at a time. This raises the
issue, what should char be on those systems? If the answer is 8-bits,
then chars have to be faked up with lots of bitshifting behind the
scenes. Char pointers need an extra two bits.
void *s therefore have to be char *s as well. However it would slow
the program down to give int *s an extra two bits to carry about.
printf("%p", ptr) has to take a pointer with an extra two bits, and if
it is passed a plain int * it will crash.

However on the vast majority of systems all pointers are equivalent.
 
F

Felix Palmen

* Shao Miller said:
Mark said:
int x;
printf("address of x %p\n", &x); /* 1*/
printf("address of x %p\n", (void *)&x); /* 2 */
[...]

And yes, an 'int *' can be converted to a 'void *', either implicitly or
explicitly. In your 'printf' #2, you accomplish an explicit conversion
via a cast.

Sure -- i think the question really was whether implicit conversion to a
void pointer should work in printf(). And I doubt that, because with a
variadic argument list, the function has to know the types at runtime
(printf() assumes to know them after parsing the format string).

As you said, the representation of a 'void *' could differ from an 'int
*' (although this would be a silly implementation, given the requirement
that any pointer must be convertible to 'void *' and vice versa, but
well, it is allowed), so printf() could end up interpreting something as
'void *' that really isn't. So I'd vote for "undefined" here.

Regards, Felix
 
M

Mark

Shao said:
The alignment and representation for an 'int *' need not be the same
as for a 'void *'. An 'int *' could be 42 bytes, whereas a 'void *'
could be 3 bytes. 'printf' is expecting a 'void *' for the "%p"
formatter.
This is interesting. Could you point to a clause from the Standard
specifying that "The alignment and representation" of pointers may be
different.
 
M

Mark

Mark said:
This is interesting. Could you point to a clause from the Standard
specifying that "The alignment and representation" of pointers may be
different.

Oh, I found it - 6.2.5p27
 
S

Shao Miller

Mark said:
This is interesting. Could you point to a clause from the Standard
specifying that "The alignment and representation" of pointers may be
different.

Absolutely. Try the C99 draft with filename 'n1256.pdf'. Please have a
look at section 6.2.5, point 27. Enjoy. :)
 
E

Eric Sosman

For the alignment ok, but the *dimension* of a pointer (an int*, a
float*, a struct blablabla *, or whatever) is always fixed (it depends
on processor, architecture, compiler, operating system, temperature,
latitude/longitude, etc..), it's an address to a memory location.

Ah, but what is in a "memory location?" On many machines, an
addressable "location" holds an eight-bit byte. But on some (mostly
older) machines, a "location" is something wider, a "word" of sixteen
or thirty-six or sixty-four or whatever bits. On such a machine, a
C implementor must choose: Either make `char' as wide as a "word" (and
accept the waste of space), or subdivide the "word" into multiple
`char' objects. In the latter case, a `char*' cannot be merely an
"address," since an address denotes a group of several `char', so the
`char*' needs further information: an address plus an indication of
which sub-"word" item is desired.

Word-addressed machines are relatively rare nowadays, but are still
found here and there, particularly in DSP's and other special-purpose
applications. Will they make a comeback? I wouldn't rule it out: For
example, the trend toward using graphics processors for highly parallel
computation may influence system designers to "harmonize" the CPU and
GPU views of memory, and since the GPU wants data in large gulps, the
memory designs may adapt to provide them. And then, lo! we may find
that a "location" is a 512-bit cache line ...

It's also possible that none of this will come to pass: It's easy
to predict the future, but difficult to do so accurately. A wise C
programmer tries not to rely on unreliable predictions, particularly
on those that sound like "Today's technology will last forever."
 
B

Ben Bacarisse

As you said, the representation of a 'void *' could differ from an 'int
*' (although this would be a silly implementation, given the requirement
that any pointer must be convertible to 'void *' and vice versa, but
well, it is allowed),

I don't think it would be silly at all. In the case where I've seen it
done it was the natural thing to do. On a word addressed machine, the
extra effort needed to maintain byte addresses can't be justified for
all pointers, so it is natural for int * and void * to use different
representations.
so printf() could end up interpreting something as
'void *' that really isn't. So I'd vote for "undefined" here.

Me too, though I am not in favour of voting to determine truth!
 
M

Malcolm McLean

     Word-addressed machines are relatively rare nowadays, but are still
found here and there, particularly in DSP's and other special-purpose
applications.  Will they make a comeback? -
A 101 uses for an octet.

Hold an ASCII character value
Hold a channel of a 24-bit rbg value
Hold an element of a normal for lighting
Hold an amino acid index
Hold 4 DNA bases
Hold an element index
Hold a charge on an atom
Hold an alpha channel

That's about all I can think of. There are plenty of cases where you
need tiny integers (eg number of children in a family), but almost
always you need so few of them that it's easier all round to use
normal integers.


Do we really need octets?
 
S

Seebs

For the alignment ok, but the *dimension* of a pointer (an int*, a
float*, a struct blablabla *, or whatever) is always fixed (it depends
on processor, architecture, compiler, operating system, temperature,
latitude/longitude, etc..), it's an address to a memory location.

Incorrect. It's whatever representation the implementation chose to use,
and on some targets, SOME pointers may be an address plus an offset within
that address (say, an octet pointer on a machine which doesn't have
addressable octets).

It's pretty common on commodity hardware that all pointers are the same
dimension, but it is NOT universally true. (It's even more not universally
true when you consider function pointers as well as object pointers.)

-s
 

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
473,954
Messages
2,570,114
Members
46,702
Latest member
VernitaGow

Latest Threads

Top