Integer sizes in C on 32 bit and 64 bit Linux

Q: How big is an int, long int etc. in C?

A: It depends. (The standard leaves it completely up to the compiler, which also means the same compiler can make it depend on options and target architecture.)

In practice I have not used anything else but gcc on Linux for a couple of years, so for myself the answer is a bit easier. However, because I don’t program C/C++ that often these days, each time I do so I soon tend to hit the question how big was that integer again, especially if interfacing with some low-level stuff and the code should work correctly on both 32 bit and 64 bit machines. At the moment I mostly use Intel architecture, so let me limit this post to Intel. (I have used a lot of ARM in the past and this week glibc with support for AArch64 came out, maybe the results can be checked against ARM later.)

type \ executable[1] 32 bit 64 bit
short int 16 bit 16 bit
int 32 bit 32 bit
long int 32 bit 64 bit
long long int 64 bit 64 bit
size_t 32 bit 64 bit
void* [2] 32 bit 64 bit

[1] A 32 bit executable can be used in a 64 bit user space (supposed a 32 bit loader and required shared libraries have been installed, a 32 bit user space can run on a 64 bit kernel and a 32 bit kernel can run on a 64 bit processor. So it’s really the word length of the executable that counts.
[2] In exotic cases pointers can have different lengths, http://stackoverflow.com/questions/6751749/size-of-a-pointer So, I’m not sure whether sizeof (void *) isn’t in fact undefined by the C standard. At least gcc compiles it without warning and returns a value, which looks correct for gcc on the Intel systems covered here.

The results where produced by the following piece of code:

#include <inttypes.h>
#include <stdio.h>

int main() {
  printf( "    short int: %zd\n" , sizeof(short int) ) ;
  printf( "          int: %zd\n" , sizeof(int) ) ;
  printf( "     long int: %zd\n", sizeof(long int) ) ;
  printf( "long long int: %zd\n", sizeof(long long int) ) ;
  printf( "       size_t: %zd\n", sizeof(size_t) ) ;
  printf( "        void*: %zd\n\n", sizeof(void *) ) ;


  printf( "PRIu32 usage (see source): %"PRIu32"\n" , (uint32_t) 42 ) ;
  return 0;
}

Slightly related the code also shows 2 features for 32/64 bit portable usage of printf. The “z” length modifier refers to size_t, see printf(3) for a couple of similar ones. The PRIu32 macro makes sure that a constant word length is used regardless of the compiler specific length of the integer types. This and several similar macros are in fact standardized in C99, they are defined in header inttypes.h.

P.S. A previous version of this post contained stupid copy paste errors resulting in wrong results. Hopefully all of them are fixed now.

Advertisements

About usrmisc

I'm a software guy and intend to write down my own miscellaneous learnings here instead of on some papers, which I don't find again. Let's see how that goes. I work mainly with Linux.
This entry was posted in programming, underTheHood. Bookmark the permalink.

2 Responses to Integer sizes in C on 32 bit and 64 bit Linux

  1. chintan says:

    Thank you its helpfull

  2. Marco Alvarado says:

    On a Raspberry Pi 2 (Raspbian, 32 bit) ARMv7

    short int: 2
    int: 4
    long int: 4
    long long int: 8
    size_t: 4
    void*: 4

    PRIu32 usage (see source): 42

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s