On 01/31/2012 07:35 PM, Chuck Guzis wrote:
I suppose it's even possible to create a C where
word addresses ==
char addresses; the char being aligned in a word, one char per word,
with the remainder of the word unsued.
The remainder of the word can't be
unused, it has to be a part of the
char type, due to requirements on the semantics of the char* type (more
on this later). But certainly for n>=16, it is possible to have the
character and int size both have exactly n bits.
So does the difference between to void* pointers
necessarily equate
to a count of chars between those addresses? Take the case of one
char per word above, for example.
The representation of a void* is unspecified, and does not have to be
the same as a char*, and you're not allowed to subtract them. It is
required that all other data types be representable as an array of char,
and it is required that the void* pointer can contain the value of any
other pointer type, so void* has to functionally be a superset of char*,
but no other pointer type needs more information storage than a char*,
so the representations of char* and void* are usually identical.
On machines that don't have native byte addressing, the char* and void*
pointers are typically implemented as a composite of a native pointer
and a byte index. This means that sizeof(char*) and sizeof(void*) may
be larger than sizeof(int*) or any other pointer type.
If you store an char* (that was not originally an int*) into a void*
pointer, then try to cast it to int*, the results are undefined, and the
pointer cast itself could crash, even if you don't dereference the pointer.
Casting some other type to an int* then back has undefined results; you
are *not* guaranteed to get a valid pointer back, let alone the original
pointer.
Do char and int addresses have to share the same
space?
No, but the char* has to be able to point to any C type, so if int and
char have separate address spaces, char* has to be able to point into
both. This is what allows memcpy() to work for any C type.
Or can chars
and ints enjoy separate addressing spaces? Do addressing spaces need
to be compatible?
Any two types other than char could be in separate address
spaces, but a
char* has to be able to point into any of them.
(I think about low-end PIC 8-bit and AVR where
data stored in code space as constants don't have the same
granularity.
The usual implementations of C on Harvard-architecture processors like
the 8-bit PIC and AVR are not complaint with the C standard. For
instance, GCC for the AVR requires a special declaration to get a char*
that has the correct C semantics of being able to point to anything
(i.e., constant data that the compiler/linker has put into program
space), and has a huge runtime penalty since the code at runtime has to
distinguish between pointers into program space and data space.
Eric