views:

93

answers:

2

Possible Duplicate:
Are there are any platforms where pointers to different types have different sizes?

I have read in several places that pointers of different types may have different representations in standard-conforming C implementations. This is one thing that makes it necessary to cast pointer arguments to printf, e.g.

int foo;
printf("address is %p\n", (void *) &foo);

I was skeptical of this and poked through the C99 standard (document WG14 N1256, available at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf). At 6.2.5.27 it reads:

A pointer to void shall have the same representation and alignment requirements as a pointer to a character type. Similarly, pointers to qualified or unqualified versions of compatible types shall have the same representation and alignment requirements. All pointers to structure types shall have the same representation and alignment requirements as each other. All pointers to union types shall have the same representation and alignment requirements as each other. Pointers to other types need not have the same representation or alignment requirements.

So, it does indeed sound like a conforming C99 implementation could use different representations for pointers of different types.

My question is this: what C implementations/architectures exist that actually use different representations for pointers of different types?

+4  A: 

Probably the most well-known is the real mode x86 processors, which could have 16-bit data pointers and 32-bit function pointers depending on the memory model you chose (or you could have 32-bit data pointers with 16-bit function pointers, or something yet again different...).

Michael Burr
Yes, I long for the days of having to choose tiny, small, medium, large and huge memory models. NOT!
paxdiablo
@paxdiablo: Can you identify any 16-bit processor/C compiler system which allowed a more convenient means of accessing memory beyond 64K? Actually, I'd like to see a new architecture based on a segmented memory model, with 32-bit selector and 32-bit offset. Very few applications need billions of objects, or need any single object to have billions of bytes; having a bounds-checked segment for each object would allow the use of 32-bit object references (instead of 64) and would allow garbage collection to be performed without having to stop everything.
supercat
Different representations for data/function pointers is a distinct issue from different representations within the category of data pointers.
R..
@super: The 65816 (http://en.wikipedia.org/wiki/65816) addressed 24 bits without segmenting. I don't know of a C compiler but I'd bet someone did it on IIgs. These days if you want to try a new architecture, just get a Verilog interpreter and write an LLVM backend… put them together and enjoy endless frustration.
Potatoswatter
@Potatoswatter: It looks as though the 65816 supports indexing across 64K boundaries, but code which works across 64K boundaries will generally be slower and more cumbersome than code which doesn't have to. The 8088 spares the programmer from having to worry about 64K hard memory boundaries, since 64K segments are relocatable on 16-byte boundaries.
supercat
+4  A: 

Classic Cray (don't know about their new products) couldn't address characters with regular pointers, so char* and therefore void* were larger than int*.

Potatoswatter
The same would have applied to the CDC Cyber processors, if anyone ever got around to implementing a C compiler....
wallyk
Also some DSPs. DSPs often have large smallest addressable word size (e.g. 24 bits), so if a compiler provides packed strings (those with less than 24 bits per char), `char*` has to encode an offset within word in addition to address.
atzz