4

Does C guarantee that sizeof(long) == sizeof(void*)? If not, why is it used so extensively in Linux kernel source code?

I looked at sizeof (int) == sizeof (void*)? but that talks about sizeof(int) vs sizeof(void *).

Daniel Walker
  • 6,380
  • 5
  • 22
  • 45
ZeZNiQ
  • 612
  • 7
  • 14

2 Answers2

11

No, the C standard does not guarantee that sizeof(long) == sizeof(void *).

In practice, on Windows 64-bit systems, the values are 4 for sizeof(long) and 8 for sizeof(void *). This design conforms to the C standard. See also What is the bit-size of long on 64-bit Windows?

Those implementing the Linux kernel have presumably decided that they'll never port the code to a system that follows the Windows 64-bit LLP64 (long long and pointers are 64-bit quantities) system, and therefore don't need to concern themselves with whether the sizes are different. Both the 32-bit systems (ILP32) and the 64-bit systems (LP64) do have sizeof(long) == sizeof(void *). But the C standard does not guarantee it.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    BTW: Windows is irrelevant.It was designed ot be. – wildplasser Aug 24 '20 at 23:33
  • 1
    IIRC [and I could be wrong about this], the reason windows went with LLP64 was because it originally had code where `int` was 16 bits [8086 with DOS and 386 with win16]. So, a lot of software, to get a 32 bit number, used `long`. This was fine until we get to a 64 bit machine. Then, to maintain backwards compatibility they chose the model that broke the least amount of software. – Craig Estey Aug 25 '20 at 01:31
  • @CraigEstey — what you describe matches pretty well with my understanding of how Windows ended up where it is. – Jonathan Leffler Aug 25 '20 at 01:38
  • "Port the code to a system that..." is missing the point - here, Linux **is the system** and *its ABI*, not C, defines `long` as having the same size as pointers. – R.. GitHub STOP HELPING ICE Aug 25 '20 at 03:37
  • @R..GitHubSTOPHELPINGICE Linux is a freestanding system designed for x86. The size of long and the ABI for writing the Linux OS is strictly speaking determined by the specific x86 compiler port. Porting Linux to a different x86 compiler isn't gonna happen, simply because the code base is married with gcc, relying heavily on gcc-specific behavior and non-standard extensions. – Lundin Aug 25 '20 at 11:17
  • @Lundin: The target platform (here, "Linux x86") defines its ABI. A compiler that does not match that ABI is a compiler for a different platform. – R.. GitHub STOP HELPING ICE Aug 25 '20 at 15:25
  • pointer must be 64bit quantities in 64bit architectures. What can chenge size is the size of a long. Again, they don't need to be the same. In linux 64bit long is 64 bit, and pointers are 64bit also. – Luis Colorado Aug 25 '20 at 18:21
3

The only guarantees are:

  • void * and char * have the same size and alignment;
  • Pointers to qualified types have the same size and alignment as pointers to their unqualified equivalents (i.e., sizeof (const int *) == sizeof (int *));
  • All struct pointer types have the same size and alignment;
  • All union pointer types have the same size and alignment;

That's it.

If Linux kernel developers are writing code that assumes sizeof (long) == sizeof (void *), then they've decided to limit which platforms they're going to support. Which is absolutely fine - you don't have to support every oddball architecture out there.

John Bode
  • 119,563
  • 19
  • 122
  • 198