是否有标准方法可以在编译时确定系统是 32 位还是 64 位?
我需要设置 #ifdef
- 检查条件编译。我想自动化该过程,但无法指定目标操作系统/机器。有什么方法可以让预编译器判断它是在 32 位还是 64 位上运行吗?
(解释)我需要定义一个 64 位大小的类型。在 64 位操作系统上它是一个 long,在大多数其他操作系统上它是一个 long long。
我找到了这个答案 - 这是正确的方法吗?
[编辑] 编译器宏的便捷参考
I need to set #ifdef
- checks for conditional compile. I want to automate the process but cannot specify the target OS/machine. Is there some way that the pre-compiler can resolve whether it it is running on 32-bit or 64-bit?
(Explanation) I need to define a type that is 64 bits in size. On 64bit OS it is a long, on most others it is a long long.
I found this answer - is this the correct way to go?
[edit] a handy reference for compiler macros
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
您可以可靠执行的唯一编译检查是 sizeof(void*) == 8,对于 x64 为 true,对于 x86 为 false。这是一个 constexpr,您可以将其传递给模板,但您可能会忘记使用 ifdef。没有独立于平台的方法来了解目标架构的地址大小(在预处理时),您需要向 IDE 索要一种方法。该标准甚至没有地址大小的概念。
The only compile check you can do reliably would be
sizeof(void*) == 8
, true for x64 and false for x86. This is a constexpr and you can pass it to templates but you can forget using ifdef with it. There is no platform-independent way to know the address size of the target architecture (at pre-process time), you will need to ask your IDE for one. The Standard doesn't even have the concept of the address size.不,宏没有标准语言支持来确定预处理器阶段机器是 64 位还是 32 位。
No there is no standard language support for macro to determine if the machine is a 64-bit or 32-bit at preprocessor stage.
为了响应您的编辑,有一种“适合您的无宏”方法来获取 64 位类型。
如果您需要可容纳 64 位的类型,则使用
#include
并使用int64_t
或uint64_t
。您还可以使用提供的标准整数类型通过提升。另一种选择是使用
long long
。从技术上讲,它不是 C++ 标准的一部分(它将在 C++0x 中),但几乎每个编译器都支持。In response to your edit, there is a "macro-less for you" way to get a type that is 64 bits.
if you need a type that can hold 64 bits, then
#include <cstdint>
and use eitherint64_t
oruint64_t
. You can also use the Standard Integer Types provided by Boost.Another option is to use
long long
. It's technically not part of the C++ standard (it will be in C++0x) but is supported on just about every compiler.我会查看跨平台库的源代码。这是相当大的一部分。每对操作系统和编译器都有自己的一组定义。您可以查看几个库:
http://www.libsdl.org/
\include\SDL_config*.h
(几个文件)http://qt.nokia.com/
\src\corelib\global\qglobal.h< /代码>
I would look at source code for a cross-platform library. It is a quite large part. Every pair of OS and compiler has own set of definitions. Few libraries You may look at:
http://www.libsdl.org/
\include\SDL_config*.h
(few files)http://qt.nokia.com/
\src\corelib\global\qglobal.h
Boost 吸收了旧的 Predef 项目。您需要 架构宏,更具体地说
BOOST_ARCH_X86_32
/BOOST_ARCH_X86_64
,假设您只关心 x86。如果您需要更广泛的检测(例如 ARM64),请将相关宏添加到您的检查中,或者检查您实际想要检查的内容,例如
Boost has absorbed the old Predef project. You'll want the architecture macros, more specifically
BOOST_ARCH_X86_32
/BOOST_ARCH_X86_64
, assuming you only care about x86.If you need a wider detection (e.g. ARM64), either add the relevant macro's to your check, or check what you actually want to check, e.g.
嗯,答案显然是特定于操作系统的,所以你需要缩小你的需求范围。
例如,在 Unix 上,
uname -a
通常会提供足够的信息来区分操作系统的 32 位版本和 64 位版本。该命令可以由您的预编译器调用。根据其输出,可以适当地设置编译器标志。
Well, the answer is clearly going to be OS-specific, so you need to narrow down your requirements.
For example, on Unix
uname -a
typically gives enough info to distinguish a 32-bit build of the OS from a 64-bit build.The command can be invoked by your pre-compiler. Depending on its output, compiler flags can be set appropriately.
我很想将检测从代码中提取出来并将其放入 Makefile 中。然后,您可以利用系统工具来检测和设置您在代码中切换的适当宏。
在你的 Makefile 中...
在你的代码中...
I would be tempted to hoist the detection out of the code and put that into the Makefile. Then, you can leverage system tools to detect and set the appropriate macro upon which you are switching in your code.
In your Makefile ...
In your code ...
最简单的方法可能是比较 int 和 long long 的大小。虽然您不能在预处理器中执行此操作,但可以在
static_assert
中使用它。编辑:哇所有反对票。我把我的观点说得更清楚了。而且由于 MSVC 的工作方式,我似乎应该提到“long long”而不是“long”。
Probably the easiest way might be comparing the size of
int
andlong long
. You cannot do it in the pre-processor though but you can use it instatic_assert
.Edit: WoW all the negative votes. I made my point a bit more clear. Also it appears I should have mentioned 'long long' rather than 'long' because of the way MSVC works.