检测 C 中的 64 位编译
是否有 C 宏或某种方式可以检查我的 C 程序在 C 编译时是否编译为 64 位或 32 位?
编译器:GCC 我需要检查的操作系统:Unix/Linux
另外,在运行我的程序时如何检查操作系统是否支持 64 位?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
是否有 C 宏或某种方式可以检查我的 C 程序在 C 编译时是否编译为 64 位或 32 位?
编译器:GCC 我需要检查的操作系统:Unix/Linux
另外,在运行我的程序时如何检查操作系统是否支持 64 位?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(10)
GLIBC 本身使用它(在
inttypes.h
中):GLIBC itself uses this (in
inttypes.h
):相同的程序源可以(并且应该能够)在64位计算机、32位计算机、36位计算机中编译......
所以,仅通过查看源代码,如果它有什么好处,你就不能告诉它如何被编译。如果源代码不太好,则可以猜测程序员假设将使用什么来编译它。
我对你的回答是:
有一种方法可以检查源文件所需的位数仅针对不良程序。
无论编译多少位,您都应该努力使您的程序正常运行。
The same program source can (and should be able to) be compiled in 64-bit computers, 32-bit computers, 36-bit computers, ...
So, just by looking at the source, if it is any good, you cannot tell how it will be compiled. If the source is not so good, it may be possible to guess what the programmer assumed would be used to compile it under.
My answer to you is:
There is a way to check the number of bits needed for a source file only for bad programs.
You should strive to make your programs work no matter on how many bits they will be compiled for.
使用此 UINTPTR_MAX 值来检查构建类型。
Use this UINTPTR_MAX value to check build type.
有多个预定义的GCC定义。尽管 URL 中有“cpp”,但大多数定义也可以在 C 中工作(如果没有说明不同)。我建议使用这些定义之一,因为它们不需要包含头文件。它们始终可用并由 GCC 本身定义(而不是由头文件)。
或者:
还有
__LONG_MAX__
和__LONG_WIDTH__
但页面说你不应该使用没有头文件的那些。There are multiple predefined GCC defines. Although there is "cpp" in the URL most defines also work in C (if not stated different). I recommend using one of those defines because they don't require to include a header file. They are always available and defined by GCC itself (not by a header file).
or:
There is also
__LONG_MAX__
and__LONG_WIDTH__
but the page says you shouldn't use those without header file.这个问题不明确,因为它没有指定要求是针对 64 位指针还是 64 位本机整数算术,或两者兼而有之。
其他一些答案已经指出了如何检测 64 位指针。尽管问题字面上规定“编译为”,但请注意,这并不能保证 64 位地址空间可用。
对于许多系统,检测 64 位指针相当于检测未模拟 64 位算术,但不能保证所有潜在场景都如此。例如,尽管 Emscripten 使用 Javascript 数组模拟内存,但其最大大小为232-1,为了提供编译针对 64 位的 C/C++ 代码的兼容性,我相信 Emscripten 是 与限制无关(尽管我还没有测试过这一点)。然而,无论编译器规定的限制如何,Emscripten 始终 使用 32 位算术。因此,Emscripten 似乎会采用针对 64 位 int 和 64 位指针的 LLVM 字节代码,并最大限度地模拟它们的 Javascript 能力。
我最初建议按如下方式检测 64 位“本机”整数,但正如 Patrick Schlüter 指出的那样,这只检测 ILP64 的罕见情况:
因此,正确的答案是,通常您不应该基于以下内容对模糊的“64 位”分类的地址空间或算术效率做出任何假设编译器报告的限制值。您的编译器可能支持特定数据模型的不可移植预处理器标志或 微处理器架构,但考虑到问题针对 GCC 并根据 Emscripten场景(其中 Clang 模拟 GCC)甚至这些可能会产生误导(尽管我还没有测试过)。
一般来说,这些场景都不能提供任何可靠的指示64位地址空间和非模拟64位算术是否可用,因此它们基本上是无用的(对于 em>所说的属性),除非在不可知的构建系统的上下文中。因此,对于所述属性,最好设置构建宏,以便构建系统可以选择编译哪个变体。
The question is ambiguous because it doesn't specify whether the requirement is for 64-bit pointers or 64-bit native integer arithmetic, or both.
Some other answers have indicated how to detect 64-bit pointers. Even though the question literally stipulates "compiled as", note this does not guarantee a 64-bit address space is available.
For many systems, detecting 64-bit pointers is equivalent to detecting that 64-bit arithmetic is not emulated, but that is not guaranteed for all potential scenarios. For example, although Emscripten emulates memory using Javascript arrays which have a maximum size of 232-1, to provide compatibility for compiling C/C++ code targeting 64-bit, I believe Emscripten is agnostic about the limits (although I haven't tested this). Whereas, regardless of the limits stated by the compiler, Emscripten always uses 32-bit arithmetic. So it appears that Emscripten would take LLVM byte code that targeted 64-bit
int
and 64-bit pointers and emulate them to the best of Javascript's ability.I had originally proposed detecting 64-bit "native" integers as follows, but as Patrick Schlüter pointed out, this only detects the rare case of ILP64:
So the correct answer is that generally you shouldn't be making any assumptions about the address space or arithmetic efficiency of the nebulous "64-bit" classification based on the values of the limits the compiler reports. Your compiler may support non-portable preprocessor flags for a specific data model or microprocessor architecture, but given the question targets GCC and per the Emscripten scenario (wherein Clang emulates GCC) even these might be misleading (although I haven't tested it).
Generally speaking none of these scenarios can be relied upon to give any reliable indication of whether a 64-bit address space and non-emulated 64-bit arithmetic is available, thus they are basically useless (w.r.t. to said attributes) except in the context of a build system that is not agnostic. Thus for said attributes, it is preferred to set build macros that so the build system can select which variant is compiled.
既然您标记了此“gcc”,请尝试
Since you tagged this "gcc", try
这是正确且可移植的测试,不假设 x86 或其他任何东西:
Here is the correct and portable test which does not assume x86 or anything else:
编译器和平台中立的解决方案是这样的:
避免使用以一个或多个下划线开头的宏。它们不是标准的,并且可能在您的编译器/平台上丢失。
A compiler and platform neutral solution would be this:
Avoid macros that start with one or more underscores. They are not standard and might be missing on your compiler/platform.
一个简单的问题会让语言律师感到不安。
由于它是一个常量表达式,优化编译器将放弃测试,只将正确的代码放入可执行文件中。
An easy one that will make language lawyer squeem.
As it is a constant expression an optimizing compiler will drop the test and only put the right code in the executable.
使用特定于编译器的宏。
我不知道您的目标架构是什么,但既然您不要指定它,我将假设普通的英特尔机器,所以您很可能有兴趣测试 Intel x86 和 AMD64。
例如:
但是,我更喜欢将它们放在单独的标头中并定义我自己的编译器中立宏。
Use a compiler-specific macro.
I don't know what architecture you are targeting, but since you don't specify it, I will assume run-of-the-mill Intel machines, so most likely you are interested in testing for Intel x86 and AMD64.
For example:
However, I prefer putting these in the separate header and defining my own compiler-neutral macro.