优雅而安全的方法来确定架构是32位还是64位

时间:2009-08-17 14:17:20

标签: c architecture gcc cpu clang

正如标题所说,是否有任何优雅而安全的方法来确定架构是32位还是64位。通过优雅,您可以想到精确,正确,简短,干净和智能的方式。通过安全,在标准,C89 / C99和操作系统独立性方面考虑安全。

7 个答案:

答案 0 :(得分:9)

简短回答:

答案很长:这取决于太多的OS /编译器组合。例如,在运行时,在linux上,您可以查询proc文件系统,而在Windows上,您可以查询寄存器。

您可以使用以下内容证明用于编译的编译器具有32/64位目标:

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

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

这可以在少数假设下工作(例如,它在运行时工作)。您可以为您的平台搜索编译时#define,但这是一个众所周知的混乱。

答案 1 :(得分:8)

如果您正在使用GCC(如标签中所示),您可以测试,作为编译时测试

#if __SIZEOF_POINTER__ == 8

找出它是否是64位系统。在使用之前,请确保您使用的GCC版本完全定义__SIZEOF_POINTER__

答案 2 :(得分:3)

指针的大小对测试来说并不是一件好事 - 无论如何,在标准C中你可以用这个测试的结果做很多。

我的建议是测试((size_t)-1),这是C理解的最大对象大小:

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

如果它大于0xffffffffUL那么你原则上可以有大于2**32 - 1字节的对象,这看起来比一个模糊的“32位与64位”更有意义的测试。

(例如,如果您知道size_t的最大值仅为2**32 - 1,则尝试mmap()大于1或2 GB的区域毫无意义。)< / p>

答案 3 :(得分:2)

最常见的方法是测试sizeof(void*)sizeof(int)(请注意,它们不一定必须相同)。

x86 / x64 CPU的另一种可能性是测试'lm'标志。如果存在,CPU会理解AMD64指令集。

答案 4 :(得分:2)

遗憾的是,安全便携的技术是不可能的(因为安全和便携只允许您使用C标准中的规则)。

sizeof(int)与一些更常见的编译器可能会给你4个32位平台和8个64位平台,但这不能保证。 所有C标准都说,int应该是目标计算的“自然”大小,因此很多编译器将sizeof(int)保留为4,即使在64位世界中也是如此,理由是它“足够”

sizeof(void*)更好,因为指针必须是适当的大小才能解决整个地址空间。因此sizeof(void*)可能会给你4或8个。 从技术上讲,即使这样也不能得到保证,因为sizeof给出了存储内容所需的字节数,而一个字节不必是8位。技术上,字节是存储器的最小可寻址单元,在人们习惯的大多数平台上恰好是8位。 8位可寻址非常常见,但我使用16位可寻址和16位字大小的芯片(因此sizeof(int)为1)。 因此,如果您的字节大小不是8位,那么sizeof(void*)可以为您提供各种值。

另一方面,如果您只是想区分x86和x64(32位和64位PC处理器),那么sizeof(void *)就足够了,并且可以在编译器之间移植。

答案 5 :(得分:1)

代码库上的32位或数据库上的32位。 :-) 8086处理器具有带有20位代码存储器的16位数据。而且,现代的Havard机器在代码/数据分离方面做得很奇怪......

您可以检查x86处理器的cpuid指令。其他处理器系列可能没有这样的指令...... YMMV。

答案 6 :(得分:1)

int iedx;

__asm
{

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

     if (iedx & (1 << 29))
       {
        return 1;
       }
     return 0;