8

In designing a new programming language, is it safe to assume that a C int and a pointer are the same size on the machine?

Shog9
  • 156,901
  • 35
  • 231
  • 235
compman
  • 2,174
  • 2
  • 18
  • 26
  • 4
    Probably a stack overflow question. – Orbling Jan 01 '11 at 16:08
  • See also: [C++: Is it safe to cast pointer to int and later back to pointer again?](http://stackoverflow.com/questions/3567905/c-is-it-safe-to-cast-pointer-to-int-and-later-back-to-pointer-again) – Shog9 Jan 01 '11 at 19:26
  • 1
    possible duplicate of [sizeof (int) == sizeof (void\*)?](http://stackoverflow.com/questions/502811/sizeof-int-sizeof-void) – Amro Jul 26 '13 at 04:12

7 Answers7

18

No. A pointer may be larger or smaller than an integer in size. If you need to pass a pointer as an integer for some reason (like performing integer, rather than pointer, arithmetic), they are guaranteed to fit into an intptr_t.

They are not guaranteed to fit into a size_t as suggested in another answer, but in practice it is unlikely that they won't, since the largest addressable size is usually equal to the largest addressable address.

5

No, not at all. Many compilers do not have them as the same size.

Puppy
  • 144,682
  • 38
  • 256
  • 465
4

No, especially in 64 bit environments:

LP64 This covers *nix environments but the same is true in windows for LLP64.

2

no, but a pointer should be the same size as a intptr_t.

dan_waterworth
  • 6,261
  • 1
  • 30
  • 41
  • It seems that sizeof(int) != sizeof(int *) with the machine and compiler that I'm using at the moment... so if something similar is safe, it doesn't involve int. – compman Jan 01 '11 at 16:04
  • 1
    @user9521: As Dan says, always use the `size_t` types. The main issue with converting code to x64 is the prevalence of people assuming the int size is the same, that practice was deprecated many years ago. – Orbling Jan 01 '11 at 16:10
  • 3
    -1 - De facto you are likely correct, but de jure you are wrong. On segmented (and other kinds of pathological) memory architectures, size_t may be smaller than intptr_t. http://stackoverflow.com/questions/1464174/size-t-vs-intptr-t. –  Jan 01 '11 at 17:23
  • Technically, your answer is still wrong even after the edit. An intptr_t can _safely store a pointer_, meaning _it is at least as large_. When sizeof(int) == sizeof(void*), then usually that is also sizeof(intptr_t). But I do not believe there is a requirement that sizeof(int) <= sizeof(void*), nor a requirement that sizeof(intptr_t) = max(sizeof(void*), sizeof(int)). –  Feb 14 '11 at 20:20
1

I think you mean size of data types as defined by platform not C lang. To best of my knowledge C doesn't define any specific size for the data types. The answer to your question is you can't assume this, for example On win32 sizeof(int) == sizeof(pointer) == 4 bytes however on win64 sizeof(int) == 4 and sizeof(pointer) == 8

Gaurav
  • 794
  • 2
  • 11
  • 32
  • 2
    The C language defines several minimum data sizes (e.g. size_t must be at least 16 bits), relational sizes (long can't be shorter than short), as well as some fixed-size types (uint32_t is exactly 32 bits). –  Jan 01 '11 at 17:20
  • @Joe you are right, I should have restricted my answer to relative size of int and pointer. – Gaurav Jan 01 '11 at 20:23
  • @Joe: It seems that uint32_t first showed up in the C standard in C99 (see http://en.wikipedia.org/wiki/Stdint.h) because that's when stdint.h became part of the standard. (I don't know if implementations would sometimes provide it before C99.) – compman Jun 28 '11 at 18:39
  • @compman: Before, most implementations typically would define integer types that had fixed sizes; but, since that's not portable, lots of projects have their own ways of defining these, typically using autoconf to set them to the correct equivalents to get the size right for the current compiler. You can compile and run a small C program to tell you the sizeof(short), sizeof(int), etc., then use the result to write a header file that has the appropriate typedefs for int16, int32, etc. – Nate C-K Jun 23 '12 at 15:18
1

No; on my MacOS X 10.6.5. machine, an int is 32 bits and a pointer is 64 bits by default.

If you need an integer that's the right size to hold a pointer too, use #include <inttypes.h> (or <stdint.h>) and uintptr_t - assuming you have C99 support, or can simulate it.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
-2

I believe the Linux Kernel passes pointers as unsigned long's. They are guaranteed to be at least the same size as a pointer :)

tperk
  • 93
  • 2
  • 3
    No. Linux guarantees they are the same size. The C language makes no promises whatsoever. – R.. GitHub STOP HELPING ICE Jan 02 '11 at 03:21
  • This is actually a good answer because it shows some Kernel behavior, and their disregard for C language rules. It causes bugs in real life, like OpenSSL's [Bug 4441: VIA C7-D processor: Hang in 30-test_afalg.t](https://rt.openssl.org/Ticket/Display.html?id=4441). It appears to be because the kernel is casting pointers (i686, 32-bit) to integrals of larger size (unsigned long and then stored in a `__u64`). – jww Mar 18 '16 at 08:10