64 位 Windows 中的 sizeof(long)

发布于 2024-12-07 11:59:02 字数 657 浏览 0 评论 0原文

我已经下载了 MinGW-64,因此我现在可以使用 g++ 4.7.0(实验性)为 Windows 7 编译 64 位程序。但下面一行:

cout << sizeof(long) << " " << sizeof(void*) << endl ;

打印 4 8,而不是 8 8。 g++ 4.6.0 的文档说:

64位环境设置int为32位,long和指针为64位

有人知道为什么sizeof(long)不是8吗?

编辑添加:我感到困惑的根源是用于 64 位 Windows 的 g++ 4.7.0 还不是 GNU 编译器集合的正式部分。它是第一个具有 32 位 long 的 64 位版本,因此文档根本不适用于它。事实上,如果您访问相关网页IA-32/x86-64 组成如下:

...

I have downloaded MinGW-64, so I can now compile 64-bit programs for Windows 7, using g++ 4.7.0 (experimental). But the following line:

cout << sizeof(long) << " " << sizeof(void*) << endl ;

prints 4 8, not 8 8. The documentation for g++ 4.6.0 says:

The 64-bit environment sets int to 32 bits and long and pointer to 64 bits

Does anybody know why sizeof(long) is not 8?

Edited to add: The source of my confusion was that g++ 4.7.0 for 64-bit Windows is not (yet) an official part of the GNU Compiler Collection. And it's the first 64-bit version with a 32-bit long, so the documentation simply doesn't apply to it. Indeed, if you go to the relevant web page, the full entry for IA-32/x86-64 consists of this:

...

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

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

发布评论

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

评论(6

人事已非 2024-12-14 11:59:02

因为它不一定是这样。 C++ 标准只要求它(如果内存允许)至少 32 位宽,并且至少与 int 一样大。

MSVC(以及 Windows 使用的 ABI)将 long 定义为 32 位宽,MingW 也遵循这一做法,因为当编译器与主机操作系统一致时,它会更有用

Because it doesn't have to be. The C++ standard only requires that it is (if memory serves) at least 32 bits wide, and at least as big as int.

MSVC (and the ABI used by Windows) defines long to be 32 bits wide, and MingW follows suit because well, the compiler is a lot more useful when it agrees with the host OS

も让我眼熟你 2024-12-14 11:59:02

在 microsoft windows 操作系统上,您有 LLP64,因此 long 的大小为 32 位。 (见下表)

引用维基百科:

在32位程序中,指针和整数等数据类型一般具有相同的长度;在 64 位机器上不一定如此。
因此,在 C 及其后代(例如 C++ 和 Objective-C)等编程语言中混合数据类型可以在 32 位实现上运行,但不能在 64 位实现上运行。
在 64 位机器上的 C 和 C 派生语言的许多编程环境中,“int”变量仍然是 32 位宽,但长整型和指针是 64 位宽。
这些被描述为具有 LP64 数据模型。另一种替代方案是 ILP64 数据模型,其中所有三种数据类型均为 64 位宽,甚至 SILP64(其中“短”整数也是 64 位宽)。
然而,在大多数情况下,所需的修改相对较小且简单,并且许多编写良好的程序可以简单地为新环境重新编译而无需更改。
另一种替代方案是 LLP64 模型,它通过将 int 和 long 保留为 32 位来保持与 32 位代码的兼容性。 “LL”指的是“长整型”类型,在所有平台上至少为 64 位,包括 32 位环境。

Type           ILP64   LP64   LLP64
char              8      8       8
short            16     16      16
int              64     32      32
long             64     64      32
long long        64     64      64
pointer          64     64      64

On the microsoft windows OS you have LLP64 so the size of long is 32 bit. (see the table below)

Quote from wikipedia:

In 32-bit programs, pointers and data types such as integers generally have the same length; this is not necessarily true on 64-bit machines.
Mixing data types in programming languages such as C and its descendants such as C++ and Objective-C may thus function on 32-bit implementations but not on 64-bit implementations.
In many programming environments for C and C-derived languages on 64-bit machines, "int" variables are still 32 bits wide, but long integers and pointers are 64 bits wide.
These are described as having an LP64 data model. Another alternative is the ILP64 data model in which all three data types are 64 bits wide, and even SILP64 where "short" integers are also 64 bits wide.
However, in most cases the modifications required are relatively minor and straightforward, and many well-written programs can simply be recompiled for the new environment without changes.
Another alternative is the LLP64 model, which maintains compatibility with 32-bit code by leaving both int and long as 32-bit. "LL" refers to the "long long integer" type, which is at least 64 bits on all platforms, including 32-bit environments.

Type           ILP64   LP64   LLP64
char              8      8       8
short            16     16      16
int              64     32      32
long             64     64      32
long long        64     64      64
pointer          64     64      64
尸血腥色 2024-12-14 11:59:02

MinGW 旨在构建 Windows 应用程序和 Microsoft 平台 ABI 指定 intlong 具有相同的 32 位大小。如果 MinGW 定义的 long 与 MSVC 不同,则大多数使用 long 的现有 Windows 应用程序在使用 MinGW 编译时都会崩溃。

话虽如此,Cygwin x86_64 确实遵循 Windows 上的 LP64 约定,就像在 Linux 上一样 (来源)。

因此,您可以使用它来构建一个 Windows 应用程序,其中 long 的大小为 8 个字节:)

测试用例:

#include <stdio.h>
#include <windows.h>

int CALLBACK WinMain(HINSTANCE a, HINSTANCE b, LPSTR c, int d)
{
  char buf[100];
  snprintf(buf, sizeof(buf),
    "sizeof(int)=%d, sizeof(long)=%d, sizeof(long long)=%d\n",
     sizeof(int), sizeof(long), sizeof(long long));
  MessageBox(NULL, buf, "Cygwin Test", MB_OK);
  return 0;
}

编译为:C:\cygwin64\bin\gcc.exe -mwindows -m64 cygwin-test.c -o cygwin-test

输出:

使用 Cygwin 的 Windows 64 位 LP64

MinGW is designed to build Windows applications, and the Microsoft platform ABI specifies that int and long have the same size of 32 bits. If MinGW defined long differently from MSVC, most existing Windows apps that use long would break when compiled using MinGW.

Having said that, Cygwin x86_64 does follow the LP64 convention on Windows, just like on Linux (source).

So you can use that to build a Windows app where the size of long is 8 bytes :)

Test case:

#include <stdio.h>
#include <windows.h>

int CALLBACK WinMain(HINSTANCE a, HINSTANCE b, LPSTR c, int d)
{
  char buf[100];
  snprintf(buf, sizeof(buf),
    "sizeof(int)=%d, sizeof(long)=%d, sizeof(long long)=%d\n",
     sizeof(int), sizeof(long), sizeof(long long));
  MessageBox(NULL, buf, "Cygwin Test", MB_OK);
  return 0;
}

Compile with: C:\cygwin64\bin\gcc.exe -mwindows -m64 cygwin-test.c -o cygwin-test

Output:

Windows 64-bit LP64 using Cygwin

抽个烟儿 2024-12-14 11:59:02

MinGW 旨在构建 WIN32 应用程序,并且 WIN32 头文件/库假定 long(或 LONG)类型为 32 位宽,即使在 64 位 Windows 上也是如此。
Microsoft 决定否则应该更改大量现有的 Windows 源代码。例如,以下结构使用 LONG 类型。

typedef struct tagBITMAPINFOHEADER { 
...
  LONG biWidth; 
  LONG biHeight; 
...
} BITMAPINFOHEADER

;

MinGW is designed to build a WIN32 application and WIN32 headers/libraries assumes the long(or LONG) type to be 32 bits wide even on a 64bit Windows.
Microsoft decided that otherwise so much of the existing Windows source codes should be changed. For example, the following structure uses LONG types.

typedef struct tagBITMAPINFOHEADER { 
...
  LONG biWidth; 
  LONG biHeight; 
...
} BITMAPINFOHEADER

;

迷途知返 2024-12-14 11:59:02

这是操作系统特定的。 Windows 的 long 大小仍然等于 32 位

It's OS specific. Windows still has size of long equal 32 bits

沩ん囻菔务 2024-12-14 11:59:02

大多数 Windows 应用程序的编写都期望 int=long=32 位。我猜 MinGW 只是确保情况仍然如此,不会有任何意外。

Most of Windows applications are written with the expectation that for all intents and purposes int=long=32 bits. I'm guessing MinGW is just making sure it's still the case and there're no surprises.

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