Sizeof (long) в 64-битном С++

Я загрузил 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 бит и длиной и указатель на 64 бит

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

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

...

Ответ 1

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

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

Ответ 2

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

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

В 32-битных программах указатели и типы данных, такие как целые числа, обычно имеют одинаковую длину; это не обязательно верно на 64-битных машинах. Таким образом, смешанные типы данных в языках программирования, таких как 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

Ответ 3

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

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

;

Ответ 4

MinGW предназначен для сборки приложений Windows, а платформа Microsoft ABI указывает, что int и long имеют одинаковый размер 32 бита. Если MinGW определен long другому, чем MSVC, большинство существующих приложений Windows, которые используют long, сломаются при компиляции с использованием 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-bit LP64 using Cygwin

Ответ 5

Эта ОС специфична. У Windows все еще есть размер длинных равных 32 бит

Ответ 6

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