Question

As title says, is there any elegant and safe way to determine if architecture is 32bit or 64bit. By elegant, you can think of precise, correct, short, clean, and smart way. By safe, think of safe in term of standard, C89/C99, and operating system independence.

Was it helpful?

Solution

The size of pointers isn't really a good thing to test - there's not much in standard C that you can do with the result of that test anyway.

My suggestion is test ((size_t)-1), the largest object size that C understands:

    if ((size_t)-1 > 0xffffffffUL)
    {
            printf("> 32 bits\n");
    }
    else
    {
            printf("<= 32 bits\n");
    }

If it's greater than 0xffffffffUL then you can in principle have objects larger than 2**32 - 1 bytes, which seems like a more meaningful test than a nebulous "32 bits versus 64 bits".

(For example, if you know that the maximum value of size_t is only 2**32 - 1, then there's no point trying to mmap() a region bigger than 1 or 2 GB.)

OTHER TIPS

short answer: no

long answer: it depends on too many OS/compiler combinations. For example at runtime, on linux you can query the proc filesystem whereas on windows you can query the register.

You can prove that the compiler that are being used for compilation has a 32/64 bits target using something like:

bool is_32bit() {
    return sizeof(int *) == 4;
} 

bool is_64bit() {
    return sizeof(int *) == 8;
} 

this could works under few assumptions (e.g. it works at runtime). You can search for compile-time #define for your platform but it is a well-known mess.

If you are using GCC (as indicated in the tags), you can test, as a compile-time test

#if __SIZEOF_POINTER__ == 8

to find out whether it's a 64-bit system. Make sure the GCC version you are using defines __SIZEOF_POINTER__ at all before using it.

The most common way is to test sizeof(void*) and sizeof(int) (note that they do not necessarily have to be the same).

Another possibility on x86/x64 CPUs is to test for the 'lm' flag. If it is present the CPU understands the AMD64 instruction set.

A safe and portable technique is unfortunately impossible (because safe and portable only allows you the rules in the C Standard).

sizeof(int) with some of the more common compilers may give you 4 for a 32 bit platform and 8 for a 64 bit platform but this is not guaranteed. All the C standard says is that an int should be the 'natural' size for calculations on the target, and so many compilers have left sizeof(int) as 4 even in a 64 bit world, on the grounds that it is 'enough'.

sizeof(void*) is better because a pointer must be the appropriate size to address the whole address space. sizeof(void*) is therefore likely to give you 4 or 8 as appropriate. Technically though, even this isn't guaranteed as a sizeof gives you the number of bytes needed to store something, and a byte doesn't have to be 8 bits. A byte is technically the smallest addressable unit of memory which just happens to be 8 bits on most platforms people are used to. 8 bit addressable is very common, but I work with chips that are 16 bit addressable and 16 bit word size (so sizeof(int) is 1). So, if your byte size is not 8 bit, then sizeof(void*) could give you a variety of values.

On the other hand, if you are merely trying to differentiate between x86 and x64 (32bit and 64 bit PC processors) then sizeof(void*) will be sufficient, and portable across compilers.

32-bit on the code bank or 32-bit on the data bank. :-) 8086 processors had 16-bit data with 20-bit code memory. Also, modern Havard machines do odd things with code/data separation...

You might check the cpuid instruction for x86 processors. Other processor families may not have such an instruction...YMMV.

int iedx;

__asm
{

mov eax, 0x80000001;
cpuid;
mov, iedx,edx;
}

     if (iedx & (1 << 29))
       {
        return 1;
       }
     return 0;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top