sizeof(long) in 64-bit Windows
Asked Answered
M

6

27

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:

...

Mathematics answered 30/9, 2011 at 7:53 Comment(5)
If you need a 64-bit wide integer use the int64_t/uint64_t or define your own. That way your code will be portable and won't rely on the platform specifics for the int/long/short sizes.Overshoot
@David: it's long long in g++.Mathematics
TonyK I prefer to use the standard types header if available or roll my own if not.Overshoot
Does this answer your question? What is the bit size of long on 64-bit Windows?Spake
Size of long vs int on x64 platform, What is the bit size of long on 64-bit Windows?Spake
C
28

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

Counterintelligence answered 30/9, 2011 at 7:59 Comment(2)
I'm not talking about the C++ standard, I'm talking about the GNU Compiler Collection's own documentation.Mathematics
I know. So read the first sentence in my answer. And the last one. The documentation you found only (I assume) describes the ABI for Linux running on x64. It says nothing about other CPUs (ARM, MIPS, Alpha, SPARC or whatever else), and it says nothing about ports to different OS'es.Counterintelligence
M
20

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
Moguel answered 30/9, 2011 at 7:57 Comment(4)
What would int32_t be defined as in ILP64? Or int16_t in SILP64?Tuppeny
@flarn2006 Of course int32_t is 32 bits and int16_t is 16 bits in all implementations that provide them.Urticaceous
@flarn2006 int32_t and int16_t are exact-width types, i.e., they are either exactly that width or they don't exist. There are additionally int_fast*_t and int_least*_t types that are at least that width, but may be larger. On SILP64 it's probable that all such minimum-width types would be 64 bits. (Necroposting, yes. =)Toastmaster
Is anything mainstream actually ILP64? Which has no 32 bit type?Scales
H
4

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

Humectant answered 29/8, 2016 at 13:39 Comment(0)
W
3

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

;

Woodall answered 3/2, 2012 at 3:41 Comment(0)
D
-1

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

Dobby answered 30/9, 2011 at 7:59 Comment(0)
G
-1

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.

Gibe answered 30/9, 2011 at 7:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.