64位Windows中的sizeof(long)

j13ufse2  于 2023-06-24  发布在  Windows
关注(0)|答案(6)|浏览(220)

我已经下载了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编译器集合的官方部分。而且它是第一个64位版本的32位long,所以文档根本不适用于它。实际上,如果您访问relevant web page,则IA-32/x86-64的完整条目包括以下内容:

...

lnvxswe2

lnvxswe21#

因为不一定是这样。C++标准只要求它至少是32位宽(如果内存可用),并且至少和int一样大。
MSVC(以及Windows使用的ABI)将long定义为32位宽,MingW也是如此,因为当编译器与主机操作系统一致时,它会更加有用

5cnsuln7

5cnsuln72#

在微软的Windows操作系统上,你有LLP 64,所以long的大小是32位。(见下表)
引用自Wikipedia:
在32位程序中,指针和数据类型(如整数)一般具有相同的长度;这在64位机器上并不一定如此。因此,在编程语言(如C)及其后代(如C++和Objective-C)中混合数据类型可能会在32位实现中起作用,但在64位实现中则不起作用。在许多64位机器上的C语言和C派生语言的编程环境中,“int”变量仍然是32位宽,但长整数和指针是64位宽。这些被描述为具有LP 64数据模型。另一种替代方案是ILP 64数据模型,其中所有三种数据类型都是64位宽,甚至SILP 64,其中“短”整数也是64位宽。然而,在大多数情况下,所需的修改相对较小和直接,许多编写良好的程序可以简单地为新环境重新编译而无需更改。另一种选择是LLP 64模型,它通过将int和long都保留为32位来保持与32位代码的兼容性。“LL”是指“long long integer”类型,在所有平台上至少为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
z2acfund

z2acfund3#

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
输出:

e4yzc0pl

e4yzc0pl4#

MinGW设计用于构建WIN32应用程序,WIN32头/库假设长(或LONG)类型即使在64位Windows上也是32位宽。微软决定,否则现有的Windows源代码应该被改变。例如,以下结构使用LONG类型。

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

;

sxpgvts3

sxpgvts35#

这是OS特定的。Windows仍然具有长等于32位的大小

hrysbysz

hrysbysz6#

大多数Windows应用程序都是在预期int=long=32位的情况下编写的。我猜MinGW只是确保它仍然是这样,没有惊喜。

相关问题