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 просто делает все возможное, и сюрпризов нет.