检测 C 中的 64 位编译

2024-10-30 08:36:00
admin
原创
57
摘要:问题描述:是否有一个 C 宏或某种方法可以帮助我在 C 编译时检查我的 c 程序是编译为 64 位还是 32 位?编译器:GCC 我需要检查的操作系统:Unix/Linux另外,在运行我的程序时如何检查操作系统是否支持 64 位?解决方案 1:由于您已将其标记为“gcc”,请尝试#if __x86_64__ ...

问题描述:

是否有一个 C 宏或某种方法可以帮助我在 C 编译时检查我的 c 程序是编译为 64 位还是 32 位?

编译器:GCC 我需要检查的操作系统:Unix/Linux

另外,在运行我的程序时如何检查操作系统是否支持 64 位?


解决方案 1:

由于您已将其标记为“gcc”,请尝试

#if __x86_64__
/* 64-bit */
#endif

解决方案 2:

以下是正确且可移植的测试,它不假设 x86 或其他任何内容:

#include <stdint.h>
#if UINTPTR_MAX == 0xffffffff
/* 32-bit */
#elif UINTPTR_MAX == 0xffffffffffffffff
/* 64-bit */
#else
/* wtf */
#endif

解决方案 3:

编译器和平台中立的解决方案是这样的:

// C
#include <stdint.h>

// C++
#include <cstdint>

#if INTPTR_MAX == INT64_MAX
// 64-bit
#elif INTPTR_MAX == INT32_MAX
// 32-bit
#else
#error Unknown pointer size or missing size macros!
#endif

避免使用以一个或多个下划线开头的宏。它们不是标准的,并且可能在您的编译器/平台上缺失。

解决方案 4:

这是一个会让语言律师感到恶心的简单问题。

if(sizeof (void *) * CHARBIT == 64) {
...
}
else {
...
}

由于它是一个常量表达式,因此优化编译器将放弃测试并仅将正确的代码放入可执行文件中。

解决方案 5:

使用特定于编译器的宏。

我不知道您的目标架构是什么,但由于您没有指定,我会假设它是普通的英特尔机器,因此您很可能对英特尔 x86和AMD64 的测试感兴趣。

例如:

#if defined(__i386__)
// IA-32
#elif defined(__x86_64__)
// AMD64
#else
# error Unsupported architecture
#endif

但是,我更喜欢将它们放在单独的标题中并定义我自己的编译器中立宏。

解决方案 6:

GLIBC 本身使用了这个(在inttypes.h):

#if __WORDSIZE == 64

解决方案 7:

同一个程序源可以(而且应该能够)在 64 位计算机、32 位计算机、36 位计算机等上进行编译……

因此,仅通过查看源代码,如果源代码不错,您无法判断它将如何编译。如果源代码不太好,也许可以猜测程序员假设将使用什么来编译它。

我的回答是:

有一种方法可以仅针对不良程序来检查源文件所需的位数。

您应该努力使您的程序能够正常工作,无论它们需要编译多少位。

解决方案 8:

使用此UINTPTR_MAX值来检查构建类型。

#include <stdio.h>
#include <limits.h>

#if UINTPTR_MAX == 0xffffffffffffffffULL               
# define BUILD_64   1
#endif

int main(void) {

    #ifdef BUILD_64
    printf("Your Build is 64-bit
");

    #else
    printf("Your Build is 32-bit
");

    #endif
    return 0;
}

解决方案 9:

有多个预定义的 GCC 定义。尽管 URL 中有“cpp”,但大多数定义也适用于 C(如果没有说明不同)。我建议使用其中一个定义,因为它们不需要包含头文件。它们始终可用并由 GCC 本身定义(而不是由头文件定义)。

#if _LP64

#endif

或者:

#if __SIZEOF_LONG__ == 8

#endif

还有__LONG_MAX____LONG_WIDTH__但是页面说你不应该使用没有头文件的文件。

解决方案 10:

这个问题含糊不清,因为它没有具体说明要求是针对 64 位指针还是64 位本机整数运算,或者两者兼而有之。

其他一些答案指出了如何检测 64 位指针。尽管问题字面上规定了“编译为”,但请注意,这并不能保证 64 位地址空间可用。

对于许多系统来说,检测 64 位指针相当于检测未模拟 64 位算术,但这并不能保证在所有潜在情况下都能如此。例如,尽管 Emscripten 使用最大大小为 2 32 -1的 Javascript 数组模拟内存,以提供编译针对 64 位的 C/C++ 代码的兼容性,但我相信 Emscripten对这些限制并不知情(尽管我没有测试过)。然而,无论编译器规定的限制如何,Emscripten 始终使用 32 位算术。因此看起来 Emscripten 将采用针对 64 位int和 64 位指针的 LLVM 字节码,并尽 Javascript 所能模拟它们。

我最初提出检测 64 位“本机”整数的方法如下,但正如 Patrick Schlüter 指出的那样,这只能检测到罕见的 ILP64 情况:

#include <stdint.h>
#if UINT_MAX >= 0xffffffffffffffff
// 64-bit "native" integers
#endif

因此,正确的答案是,通常您不应该根据编译器报告的限制值对模糊的“64 位”分类的地址空间或算术效率做出任何假设。您的编译器可能支持特定数据模型或微处理器架构的不可移植预处理器标志,但考虑到问题针对的是 GCC 和 Emscripten 场景(其中 Clang 模拟 GCC),即使这些也可能具有误导性(尽管我还没有测试过)。

一般而言,这些场景都不能可靠地指示64 位地址空间和非模拟 64 位算法是否可用,因此它们基本上是无用的(相对于所述属性),除非在非不可知的构建系统环境中。因此,对于所述属性,最好设置构建宏,以便构建系统可以选择编译哪个变体。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用