开发者

sizeof(long) in 64-bit C++

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

开发者_如何学CDoes 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:

...


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


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


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:

sizeof(long) in 64-bit C++


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

;


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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜