检测 C 中的 64 位编译

发布于 2024-10-21 04:09:46 字数 130 浏览 2 评论 0 原文

是否有 C 宏或某种方式可以检查我的 C 程序在 C 编译时是否编译为 64 位或 32 位?

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

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

is there a C macro or some kind of way that i can check if my c program was compiled as 64bit or 32bit at compile time in C?

Compiler: GCC
Operating systems that i need to do the checks on: Unix/Linux

Also how could i check when running my program if the OS is capable of 64bit?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

愁以何悠 2024-10-28 04:09:47

GLIBC 本身使用它(在 inttypes.h 中):

#if __WORDSIZE == 64

GLIBC itself uses this (in inttypes.h):

#if __WORDSIZE == 64
攒眉千度 2024-10-28 04:09:47

相同的程序源可以(并且应该能够)在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.

葬シ愛 2024-10-28 04:09:47

使用此 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\n");

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

    #endif
    return 0;
}

Use this UINTPTR_MAX value to check build type.

#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\n");

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

    #endif
    return 0;
}
新雨望断虹 2024-10-28 04:09:47

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

#if _LP64

#endif

或者:

#if __SIZEOF_LONG__ == 8

#endif

还有 __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).

#if _LP64

#endif

or:

#if __SIZEOF_LONG__ == 8

#endif

There is also __LONG_MAX__ and __LONG_WIDTH__ but the page says you shouldn't use those without header file.

旧人九事 2024-10-28 04:09:47

这个问题不明确,因为它没有指定要求是针对 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 的罕见情况

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

因此,正确的答案是,通常您不应该基于以下内容对模糊的“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:

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

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.

寄人书 2024-10-28 04:09:46

既然您标记了此“gcc”,请尝试

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

Since you tagged this "gcc", try

#if __x86_64__
/* 64-bit */
#endif
不知在何时 2024-10-28 04:09:46

这是正确且可移植的测试,不假设 x86 或其他任何东西:

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

Here is the correct and portable test which does not assume x86 or anything else:

#include <stdint.h>
#if UINTPTR_MAX == 0xffffffff
/* 32-bit */
#elif UINTPTR_MAX == 0xffffffffffffffff
/* 64-bit */
#else
/* wtf */
#endif
眼泪都笑了 2024-10-28 04:09:46

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

// 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

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

A compiler and platform neutral solution would be this:

// 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

Avoid macros that start with one or more underscores. They are not standard and might be missing on your compiler/platform.

素手挽清风 2024-10-28 04:09:46

一个简单的问题会让语言律师感到不安。

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

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

An easy one that will make language lawyer squeem.

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

As it is a constant expression an optimizing compiler will drop the test and only put the right code in the executable.

云巢 2024-10-28 04:09:46

使用特定于编译器的宏。

我不知道您的目标架构是什么,但既然您不要指定它,我将假设普通的英特尔机器,所以您很可能有兴趣测试 Intel x86AMD64

例如:

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

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

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:

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

However, I prefer putting these in the separate header and defining my own compiler-neutral macro.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文