sizeof(long) в 64-битном C++

Я скачал MinGW-64, так что теперь я могу скомпилировать 64-битные программы для Windows 7, используя g++ 4.7.0 (экспериментальный). Но следующая строка:

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

печать 4 8не 8 8, Документация для g++ 4.6.0 гласит:

В 64-битной среде для int устанавливается значение 32 бита и long, а для указателя - 64 бита.

Кто-нибудь знает почему sizeof(long) не 8?

Отредактировано, чтобы добавить: Источник моей путаницы заключался в том, что g ++ 4.7.0 для 64-битной Windows (пока) не является официальной частью коллекции компиляторов GNU. И это первая 64-битная версия с 32-битной longпоэтому документация к нему просто не относится. Действительно, если вы перейдете на соответствующую веб-страницу, полная запись для IA-32/x86-64 состоит из этого:

...

6 ответов

Решение

Потому что так не должно быть. Стандарт C++ требует только, чтобы он был (если память служит) шириной не менее 32 бит и, по крайней мере, такой же большой, как int,

MSVC (и ABI, используемый Windows) определяет long ширина 32 бита, и MingW следует тому же принципу, потому что компилятор гораздо полезнее, когда он согласен с операционной системой хоста

В ОС Microsoft Windows у вас есть LLP64, поэтому размер long составляет 32 бита. (см. таблицу ниже)

Цитата из Википедии:

В 32-битных программах указатели и типы данных, такие как целые числа, обычно имеют одинаковую длину; это не обязательно верно для 64-битных машин. Таким образом, смешивание типов данных в языках программирования, таких как C и его потомках, таких как C++ и Objective-C, может функционировать в 32-битных реализациях, но не в 64-битных реализациях. Во многих средах программирования для языков C и C на 64-битных компьютерах переменные типа int по-прежнему имеют ширину 32 бита, но длинные целые и указатели имеют ширину 64 бита. Они описаны как имеющие модель данных LP64. Другой альтернативой является модель данных ILP64, в которой все три типа данных имеют ширину 64 бита, и даже SILP64, где "короткие" целые числа также имеют ширину 64 бита. Однако в большинстве случаев требуемые модификации относительно незначительны и просты, и многие хорошо написанные программы могут быть просто перекомпилированы для новой среды без изменений. Другой альтернативой является модель LLP64, которая поддерживает совместимость с 32-битным кодом, оставляя как int, так и long 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

MinGW is designed to build Windows applications, and the Microsoft platform ABI specifies that int а также 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.

Сказав это, Cygwin x86_64 действительно следует соглашению LP64 в Windows, как и в 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

Выход:

Windows 64-битный LP64 с использованием Cygwin

MinGW предназначен для создания приложения WIN32, а заголовки / библиотеки WIN32 предполагают, что тип long(или LONG) имеет ширину 32 бита даже в 64-битной Windows. Microsoft решила, что в противном случае большая часть существующих исходных кодов Windows должна быть изменена. Например, следующая структура использует типы LONG.

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

;

Большинство приложений Windows написаны с ожиданием, что для всех намерений и целей int=long=32 бита. Я предполагаю, что MinGW просто следит за тем, чтобы все было так и не было сюрпризов.

Это зависит от ОС. Windows все еще имеет размер long, равный 32 битам

Другие вопросы по тегам