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