Are char*
, int*
, long*
or even long long*
of same size (on a given platform)?

- 347,512
- 102
- 1,199
- 985

- 691
- 1
- 7
- 13
-
2My curiosity begs the question: Why do you care? :-) – Pete Aug 06 '09 at 20:29
-
char c[100]; int *i; i = &c[0]; i = 0x5555u; question: c[0] == 0x55u? c[1] == 0x55u? – c-stranger Aug 06 '09 at 21:25
-
Assigning the address of a char to a pointer to int is just not a good idea.... – KTC Aug 06 '09 at 23:45
-
1@c-stranger: most certainly not guaranteeed. If the machine is big-endian, then the first two bytes of c would be 0. Also, there is no guarantee that c is aligned as strictly as an int would be aligned - though it probably is. – Jonathan Leffler Aug 07 '09 at 03:48
-
@Jonathan Leffler, you are incorrectly assuming int is always 4 bytes as well. – KTC Aug 07 '09 at 08:29
-
5This is important question if you are writing portable c, have a struct with pointers, and you want the memory to be aligned. https://brewx.qualcomm.com/bws/content/gi/common/appseng/en/knowledgebase/docs/kb95.html – Tero Niemi Oct 05 '12 at 21:48
8 Answers
They're not guaranteed to be the same size, although on the platforms I have experience with they usually are.
C 2011 online draft:
6.2.5 Types
...
28 A pointer tovoid
shall have the same representation and alignment requirements as a pointer to a character type.48) 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.
48) The same representation and alignment requirements are meant to imply interchangeability as arguments to functions, return values from functions, and members of unions.

- 119,563
- 19
- 122
- 198
-
16+1 for a reference to the Standard that really nails it down and covers all edge cases. – Pavel Minaev Aug 06 '09 at 20:46
Not necessarily. The standard does not guarantee sizeof(double*) == sizeof(int*)
. For instance, assume a processor with two address buses with different widths (like on some Harvard architecture processors) it could have pointers with different sizes.

- 414,610
- 91
- 852
- 789
-
12However, note that a void * has to be able to hold any data pointer. – David Thornley Aug 06 '09 at 20:31
-
Hmmm. Then why can a void* point to anything, and be properly dereferenced? After all, no information is carried along with a pointer. – xcramps Aug 06 '09 at 20:33
-
12`void*` cannot be dereferenced directly - you have to cast it back to the original type. Presumably, even if representation of pointers actually differs between types, the original representation will be restored when you cast back. – Pavel Minaev Aug 06 '09 at 20:34
-
WRONG. The size of the pointer is not the same thing as the size of the block of memory the pointer "points" to... – Charles Bretana Aug 06 '09 at 20:36
-
5Charles, you misunderstand what is talked about. It has nothing to do with size of `int` and `double` (it could be any other two types). The point is that sizes of _pointers_ themselves can differ. – Pavel Minaev Aug 06 '09 at 20:37
-
@Pavel Minaev... obviously. "Properly dereferenced" means just what it says. – xcramps Aug 06 '09 at 20:39
-
@Pavel, sorry, you are obviously correct, I read sizeof() and assumed you were measuring the size of the object the pointer is pointing to.... As I have never seen an use of the sizeof operator on a pointer, it would seem to make no sense to me to do that...) – Charles Bretana Aug 06 '09 at 20:44
-
@CharlesBretana using `sizeof` on a pointer is common when invoking `malloc` ! – M.M Oct 16 '14 at 22:20
-
@Matt McNabb, I guess if it's possible for pointers to come in different sizes on the same machine, (which I was unaware of), then it would make sense to use `sizeof()` on a pointer. Absent that scenario, it makes no sense at all - they would always be the same size... – Charles Bretana Oct 17 '14 at 13:50
-
2@CharlesBretana you still have to do `sizeof` on one of them in order to figure out how many bytes to allocate when allocating an array of pointers, since `malloc` expects a number of bytes. – M.M Oct 18 '14 at 01:17
-
@Matt, but isn't the `sizeof()` used for `malloc()` the size of the object the pointer points to, not the size of the pointer? the number of bytes passed to malloc is the number of bytes of memory to be allocated, which is the number of bytes per object, times how many objects.... not the number of bytes in pointers to those objects... – Charles Bretana Oct 20 '14 at 14:04
-
@CharlesBretana I'm talking about when you are allocating space to store pointers – M.M Oct 20 '14 at 18:54
-
ahhhh, but I was not... I was talking about why you would need `sizeof(somePointer)` for a `malloc` on a machine where pointers are all always the same size... Clearly, if they're always 8 bytes, it is silly to run `sizeof()`. – Charles Bretana Oct 20 '14 at 21:01
-
2@CharlesBretana: It's not silly at all. `sizeof` (except perhaps when applied to a variable-length array type) has exactly zero overhead; it resolves to a constant. `sizeof (some_type*)` is better than `8` simply because it's more explicit -- *and* it means the code might be portable to other systems. – Keith Thompson Jun 26 '15 at 20:48
On 16-bit embedded processors which have banked (paged) RAM and/or flash, the use of pages may lead to pointers being different sizes - though this is independent of the size of the data they point to.
For example, on Freescale's HCS12 processor which has banked flash, data pointers are all 16 bits.
However, function pointers are 16 bits for near pointers (for code in the same page as the calling function, or in unbanked flash), or 24 bits for far pointers (for code in a different page), incorporating the page number in the address.
Things are complicated if you want to store constant data in paged flash, as due to the limitation on data pointer size, the function using the data has to be in the same page as the data being accessed.
It is conceivable that a 16-bit processor with banked RAM would likewise have different sizes for near and far data pointers.

- 2,620
- 1
- 22
- 24
-
The object pointer part isn't true since HCS12 is Von Neumann and you can store objects as well as functions anywhere in flash memory just fine, optionally using banked flash. Data pointers are then either 16 or 24 bit, depending on if declared with `far` or not. Function pointers is a bit more advanced since not only the size of the pointer differs from 16 and 24, but you must also use the correct instructions on the assembler level: `JSR` versus `CALL` and `RTS` versus `RTC`. – Lundin Oct 06 '21 at 13:22
Note what the C standard says - as quoted by John Bode. Note, too, that the C standard says nothing about the sizes of pointers to functions at all.
The POSIX standard lays down some extra requirements:
2.12.3 Pointer Types
All function pointer types shall have the same representation as the type pointer to void. Conversion of a function pointer to void * shall not alter the representation. A void * value resulting from such a conversion can be converted back to the original function pointer type, using an explicit cast, without loss of information.
Note: The ISO C standard does not require this, but it is required for POSIX conformance.

- 1
- 1

- 730,956
- 141
- 904
- 1,278
-
1Note that this section has been removed from the POSIX 2013 revision of POSIX 2008. For most practical purposes, it still exists, but it is now a consequence of the behaviour of `dlsym()` rather than a more general statement. Sometime (maybe this decade), I need to write up the change. – Jonathan Leffler Oct 01 '15 at 16:48
There is no such guarantee in either C or C++ ISO standards, but in practice, I've yet to see a platform where this doesn't hold.
Note that regardless of this, reinterpret_cast
'ing one pointer to another will more often than not lead to U.B., with a few exceptions (void*
, and unsigned char*
for PODs). So would any union tricks. So the obvious question is: why would you care?

- 99,783
- 25
- 219
- 289
When programming x86 real mode with Watcom C you could have a mixed memory model using 16-bit near pointers and 32 bit far pointers.

- 7,637
- 34
- 29
In the protected mode DOS days, a function pointer and a data pointer could have different lengths because data could be in a different section.

- 65,249
- 10
- 91
- 131
Generally yes, All pointers to anything, whether they point to a int or a long or a string or an array of strings or a function, point to a single memory address, which is the same size on a machine. That is because the Processer on a machine has a an address register that these pointers are loaded into, and the size of that address register controls the size of the pointers.
The only exception might be in cases like old Intel 8088 16-bit machines where there was a two step process to determine the memory address, involving a 16 bit segment pointer, (which identified a 64K block of memory within the 1MByte address space), and then a second 16 bit memory address to identify the specific memory address within that segment. These two 16 bit addresses were then combined to get the complete 20 bit memory address. In that scenario, then, I imagine it might be possible to distinquiah between the individual 16 bit addresses, and the combined 20-bit address.

- 143,358
- 22
- 150
- 216
-
2There's no requirement for a C/C++ implementation to actually store a raw memory address in the storage location of the pointer. It can be a handle, for example (e.g. to implement pointer bounds checking). – Pavel Minaev Aug 06 '09 at 20:33
-
@Pavel, I confess that I'm not a C++ person, and I only know about Handles periphally, but as a Handle is a type of pointer, than I would venture that it has to be the same size as all other pointers on the machine. – Charles Bretana Aug 06 '09 at 20:40
-
A handle is not a type of pointer. A handle is an opaque identifier. It can be absolutely anything - for example, an index into some array elsewhere. – Pavel Minaev Aug 06 '09 at 20:43
-
Especially true of member function pointers. I got schooled on this topic recently: there is no guarantee a pointer is actually an address. It's just the best representation on most systems we use. – quark Aug 06 '09 at 21:35
-
3Consider a word-addressed CPU, where a machine address specifies the address of, say, a 32-bit word. A pointer to a smaller type, such a `char*` (let's assume `CHAR_BIT == 8`) might need to hold both a word pointer and a byte offset within the word. I've worked on Cray vector systems that did something similar, except that the byte offset was stored in the otherwise unused high-order 3 bits of the 64-bit word. – Keith Thompson Jun 26 '15 at 20:51