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

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

指针的大小并不是一个值得测试的好东西 – 标准C中你可以用这个测试的结果做多少。

我的建议是test ((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的区域是毫无意义的。)

简短的回答: 没有

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

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

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

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

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

 #if __SIZEOF_POINTER__ == 8 

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

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

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

遗憾的是,安全便携的技术是不可能的(因为安全和便携只允许您使用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 *)就足够了,并且可以在编译器之间移植。

代码库上的32位或数据库上的32位。 🙂 8086处理器具有带有20位代码存储器的16位数据。 此外,现代Havard机器通过代码/数据分离做奇怪的事情……

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

 int iedx; __asm { mov eax, 0x80000001; cpuid; mov, iedx,edx; } if (iedx & (1 << 29)) { return 1; } return 0; 
Interesting Posts