34

Possible Duplicates:
Can the Size of Pointers Vary Depending on what’s Pointed To?
Are there are any platforms where pointers to different types have different sizes?

Is it possible that the size of a pointer to a float in c differs from a pointer to int? Having tried it out, I get the same result for all kinds of pointers.

#include <stdio.h>
#include <stdlib.h>

int main()
{
    printf("sizeof(int*): %i\n", sizeof(int*));
    printf("sizeof(float*): %i\n", sizeof(float*));
    printf("sizeof(void*): %i\n", sizeof(void*));
    return 0;
}

Which outputs here (OSX 10.6 64bit)

sizeof(int*): 8
sizeof(float*): 8
sizeof(void*): 8

Can I assume that pointers of different types have the same size (on one arch of course)?

Community
  • 1
  • 1
Nils
  • 13,319
  • 19
  • 86
  • 108
  • dupe? http://stackoverflow.com/questions/1473935/can-the-size-of-pointers-vary-depending-on-whats-pointed-to – Johan Kotlinski Aug 19 '10 at 08:54
  • 1
    @kotlinski: there are two boolean questions: the title one (do they vary?) and the final one (are they the same?). WHich one are you answering? – MSalters Aug 19 '10 at 08:57
  • 2
    @MSalters: oops! the last... they are allowed to vary. – Johan Kotlinski Aug 19 '10 at 08:58
  • 1473935 is itself a dupe of http://stackoverflow.com/questions/916051/are-there-are-any-platforms-where-pointers-to-different-types-have-different-size – Gilles 'SO- stop being evil' Aug 19 '10 at 09:22
  • 2
    Aside from `near` and `far`, which are attributes the programmer ascribes when declaring a pointer and don't really apply here, old Crays had `char*` larger than other pointers because the native memory scheme didn't address bytes. – Potatoswatter Aug 19 '10 at 09:23
  • The second "possible duplicate" is a duplicate, the first not. – Nils Aug 20 '10 at 19:38

10 Answers10

23

Pointers are not always the same size on the same arch.

You can read more on the concept of "near", "far" and "huge" pointers, just as an example of a case where pointer sizes differ...

http://en.wikipedia.org/wiki/Intel_Memory_Model#Pointer_sizes

Joe
  • 46,419
  • 33
  • 155
  • 245
Johan Kotlinski
  • 25,185
  • 9
  • 78
  • 101
14

In days of old, using e.g. Borland C compilers on the DOS platform, there were a total of (I think) 5 memory models which could even be mixed to some extent. Essentially, you had a choice of small or large pointers to data, and small or large pointers to code, and a "tiny" model where code and data had a common address space of (If I remember correctly) 64K.

It was possible to specify "huge" pointers within a program that was otherwise built in the "tiny" model. So in the worst case it was possible to have different sized pointers to the same data type in the same program!

I think the standard doesn't even forbid this, so theoretically an obscure C compiler could do this even today. But there are doubtless experts who will be able to confirm or correct this.

Carl Smotricz
  • 66,391
  • 18
  • 125
  • 167
  • The standard didn't forbid it outright, but the particular details were non-standard. However, you correctly point out that you could independently choose between small and large pointers for code and data. – MSalters Aug 19 '10 at 09:02
12

Pointers to data must always be compatible with void* so generally they would be nowadays realized as types of the same width.

This statement is not true for function pointers, they may have different width. For that reason in C99 casting function pointers to void* is undefined behavior.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • 4
    All that means is that `void *` has to be at least the size of the largest other pointer type. – caf Aug 19 '10 at 12:32
  • @caf: you probably mean "other pointer to data type" and "width" instead of "size", yes I think this is what I said in my first para. That doesn't force other pointer data types to be of the same width, but it makes it very likely, since casting back from `void*` must still have all information to address the object. But you are right, a hypothetical architecture could save the low order byte of pointers for all data types that are aligned at 256 byte boundaries ;-) – Jens Gustedt Aug 19 '10 at 13:46
  • 2
    Exactly - converting from `void *` to `double *` can be lossy, but not vice-versa. – caf Aug 19 '10 at 23:53
  • 2
    Can someone explain what "width" is (as opposed to "size")? – Thomas Eding Jul 02 '11 at 00:01
  • 1
    @trinithis, comments to year old questions are not a good place to ask questions. The width is the number of bits that is effectively used for a type. E.g a `_Bool` has `sizeof` of at least one, so it occupies at least 8 bits. But usually it uses only 1 bit out of these so its width would be only 1 instead of 8. The other bits are then so-called padding bits. – Jens Gustedt Jul 02 '11 at 05:50
  • The best answer is most frequently found at the bottom. – CDR Sep 15 '13 at 09:34
10

As I understand it there is nothing in the C standard which guarantees that pointers to different types must be the same size, so in theory an int * and a float * on the same platform could be different sizes without breaking any rules.

There is a requirement that char * and void * have the same representation and alignment requirements, and there are various other similar requirements for different subsets of pointer types but there's nothing that encompasses everything.

In practise you're unlikely to run into any implementation that uses different sized pointers unless you head into some fairly obscure places.

Nigel Harper
  • 1,270
  • 9
  • 13
8

Yes. It's uncommon, but this would certainly happen on systems that are not byte-addressable. E.g. a 16 bit system with 64 Kword = 128KB of memory. On such systems, you can still have 16 bits int pointers. But a char pointer to an 8 bit char would need an extra bit to indicate highbyte/lowbyte within the word, and thus you'd have 17/32 bits char pointers.

This might sound exotic, but many DSP's spend 99.x% of the time executing specialized numerical code. A sound DSP can be a bit simpler if it all it has to deal with is 16 bits data, leaving the occasional 8 bits math to be emulated by the compiler.

MSalters
  • 173,980
  • 10
  • 155
  • 350
6

I was going to write a reply saying that C99 has various pointer conversion requirements that more or less ensure that pointers to data have to be all the same size. However, on reading them carefully, I realised that C99 is specifically designed to allow pointers to be of different sizes for different types.

For instance on an architecture where the integers are 4 bytes and must be 4 byte aligned an int pointer could be two bits smaller than a char or void pointer. Provided the cast actually does the shift in both directions, you're fine with C99. It helpfully says that the result of casting a char pointer to an incorrectly aligned int pointer is undefined.

See the C99 standard. Section 6.3.2.3

JeremyP
  • 84,577
  • 15
  • 123
  • 161
3

Yes, the size of a pointer is platform dependent. More specifically, the size of a pointer depends on the target processor architecture and the "bit-ness" you compile for.

As a rule of thumb, on a 64bit machine a pointer is usually 64bits, on a 32bit machine usually 32 bits. There are exceptions however.

Since a pointer is just a memory address its always the same size regardless of what the memory it points to contains. So a pointer to a float, a char or an int are all the same size.

Johannes Rudolph
  • 35,298
  • 14
  • 114
  • 172
  • 5
    Aehm this was not the question, the question was whether pointer to different types (float*, int*, void*) can have different sizes (on the same platform), which is not the case. – Nils Aug 19 '10 at 08:52
  • +1 Yes, in ancient 16-Bit windows there where near (16 bit) and far pointer (32 bit) depending on memory modell and usage. – stacker Aug 19 '10 at 08:52
1

Can I assume that pointers of different types have the same size (on one arch of course)?

For the platforms with flat memory model (== all popular/modern platforms) pointer size would be the same.

For the platforms with segmented memory model, for efficiency, often there are platform-specific pointer types of different sizes. (E.g. far pointers in the DOS, since 8086 CPU used segmented memory model.) But this is platform specific and non-standard.

You probably should keep in mind that in C++ size of normal pointer might differ from size of pointer to virtual method. Pointers to virtual methods has to preserve extra bit of information to not to work properly with polymorphism. This is probably only exception I'm aware of, which is still relevant (since I doubt that segmented memory model would ever make it back).

Dummy00001
  • 16,630
  • 5
  • 41
  • 63
0

There are platforms where function pointers are a different size than other pointers.

I've never seen more variation than this. All other pointers must be at most sizeof(void*) since the standard requires that they can be cast to void* without loss of information.

blucz
  • 1,606
  • 10
  • 13
-1

Pointer is a memory address - and hence should be the same on a specific machine. 32 bit machine => 4Bytes, 64 bit => 8 Bytes.

Hence irrespective of the datatype of the thing that the pointer is pointing to, the size of a pointer on a specific machine would be the same (since the space required to store a memory address would be the same.)

Assumption: I'm talking about near pointers to data values, the kind you declared in your question.

Gishu
  • 134,492
  • 47
  • 225
  • 308
  • 5
    -1, wrong. For starters it assumes pointers point to data (and a datatype) which misses function pointers. And C on DOS had a memory model with 16 bits function pointers and 20/32 bits data pointers. – MSalters Aug 19 '10 at 09:00
  • Yeah I forgot to add 'for all practical purposes' to the answers. Technically the answer might be wrong - C/C++ always has exceptions to the rule. However from the context given by the OP in the question (since I was just thinking of near (normal) pointers),I guess it answers him alright. Thanks for making me go back and read up though! – Gishu Aug 19 '10 at 09:08