4

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?

Community
  • 1
  • 1
Brad Larsen
  • 995
  • 1
  • 12
  • 20
  • 2
    possible duplicate of [Are there are any platforms where pointers to different types have different sizes?](http://stackoverflow.com/questions/916051/are-there-are-any-platforms-where-pointers-to-different-types-have-different-size) see also http://stackoverflow.com/questions/3520059/does-the-size-of-pointers-vary-in-c-closed – Potatoswatter Oct 05 '10 at 03:32
  • One interesting note - I'm pretty sure POSIX forbids different pointer representations. Can anyone verify this? I'm too lazy. – R.. GitHub STOP HELPING ICE Oct 05 '10 at 03:57
  • 1
    I queried the relation between `void *` and `char *` in these controversial questions: http://stackoverflow.com/questions/1864352/void-has-unknown-size-in-visual-c, http://stackoverflow.com/questions/1864956/byte-precision-pointer-arithmetic-in-c-when-sizeofchar-1 you might find them interesting. – Matt Joiner Oct 05 '10 at 05:12

2 Answers2

4

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
  • 333,147
  • 50
  • 533
  • 760
  • Yes, I long for the days of having to choose tiny, small, medium, large and huge memory models. NOT! – paxdiablo Oct 05 '10 at 03:29
  • @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 Oct 05 '10 at 03:48
  • 1
    Different representations for data/function pointers is a distinct issue from different representations within the category of data pointers. – R.. GitHub STOP HELPING ICE Oct 05 '10 at 03:56
  • @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 Oct 05 '10 at 04:32
  • @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 Oct 06 '10 at 04:09
4

Classic Cray (don't know about their new products) couldn't address characters with regular pointers, so char* and therefore void* were different from native vector pointers.

(See Keith's comment below, though. There may have been different ABI's in use, and by rotating the the low-order address bits to the high-order end, they did sometimes make the "fine" and "coarse" pointers compatible to a degree.)

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • The same would have applied to the CDC Cyber processors, if anyone ever got around to implementing a C compiler.... – wallyk Oct 05 '10 at 03:42
  • 1
    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 Oct 05 '10 at 04:22
  • On the T90 I worked on, native pointers pointed to 64-bit words, and `char*` and `void*` were implemented in software by storing an offset in the high-order 3 bits. `int*` and `char*` were the same size, but the representations were different (and byte-level access was *slow*). – Keith Thompson Aug 17 '11 at 03:02
  • @Keith: Thanks, corrected. I wonder if that's the way it always was? I've forgotten/lost the source I had for my info. – Potatoswatter Aug 19 '11 at 02:22
  • @Potatoswatter: It's entirely possible that earlier models had varying pointer sizes. – Keith Thompson Aug 19 '11 at 02:28