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

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

18 голосов
/ 30 сентября 2011

Я скачал 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 ]

18 голосов
/ 30 сентября 2011

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

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

13 голосов
/ 30 сентября 2011

В операционной системе 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
2 голосов
/ 29 августа 2016

MinGW предназначен для создания приложений Windows, а платформа Microsoft ABI указывает , что int и long имеют одинаковый размер 32 бита.Если MinGW определит long не так, как MSVC, большинство существующих приложений Windows, использующих long, сломаются при компиляции с использованием MinGW.

Сказав, что Cygwin x86_64 действительно следует соглашению LP64 поWindows, как и в Linux ( source ).

Таким образом, вы можете использовать это для создания приложения 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

2 голосов
/ 03 февраля 2012

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

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

;

0 голосов
/ 30 сентября 2011

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

0 голосов
/ 30 сентября 2011

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

...