sizeof (void *) - 4 на 64 цели - PullRequest
       12

sizeof (void *) - 4 на 64 цели

0 голосов
/ 17 июля 2011

Я собираю 64-битный проект C ++ для Visual Studio Pro 2010 и проверяю размер указателей.Это показывает, что sizeof (любой указатель), такой как void *, char * и т. Д., Составляет 4 байта.Это кажется неправильным для 64-битной системы.Однако sizeof (UINT_PTR) равно 8, что является правильным для 64-разрядного.

Вот мое определение препроцессора: _WIN64; _AMD64; _WINDOWS; _DEBUG; _USRDLL;
Целевой компьютер - MachineX64 (/ MACHINE: X64).

Есть ли место, где определяется размер () вещей?В противном случае, как я могу узнать, почему он дает мне неправильный размер?

Спасибо.

Редактировать: Командная строка компилятора:

/Zi /nologo /W4 /WX- /Od /D "_WIN64" /D "_AMD64" /D "_WINDOWS" /D "_DEBUG" /D "_USRDLL" /D "_WINDLL" /D "_MBCS" /D "_AFXDLL" /Gm /EHsc /RTC1 /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fp"x64\Debug\S2TalkerDLL.pch" /Fa"x64\Debug\" /Fo"x64\Debug\" /Fd"x64\Debug\vc100.pdb" /Gd /errorReport:queue 

Командная строка компоновщика:

/OUT:"C:\Users\xxx\Documents\Visual Studio 2010\Projects\S2TalkerDLL\x64\Debug\S2TalkerDLL.dll" /INCREMENTAL /NOLOGO /DLL "WINMM.lib" /DEF:".\S2TalkerDLL.def" /MANIFEST /ManifestFile:"x64\Debug\S2TalkerDLL.dll.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"C:\Users\xxx\Documents\Visual Studio 2010\Projects\S2TalkerDLL\x64\Debug\S2TalkerDLL.pdb" /SUBSYSTEM:WINDOWS /PGD:"C:\Users\xxx\Documents\Visual Studio 2010\Projects\S2TalkerDLL\x64\Debug\S2TalkerDLL.pgd" /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X64 /ERRORREPORT:QUEUE 

enter image description here

enter image description here

1 Ответ

3 голосов
/ 17 июля 2011

Постойте, вы получаете sizeof() значения от Intellisense или от компилятора?То есть пытались ли вы скомпилировать и запустить что-то вроде этого:

#include <cstdio>
int main()
{
    ::printf("%d\n", sizeof(void*));
    return 0;
}

Я спрашиваю, потому что из опубликованных вами снимков экрана видно, что вы используете Intellisense для определения того, что sizeof() оценивает.

Intellisense - это нечто совершенно отдельное от компилятора.Это просто инструмент, который пытается проанализировать ваш (вероятно, неполный) код для целей автозаполнения.Он может знать или не знать о конкретных настройках компилятора / компоновщика, таких как /MACHINE:X64, поэтому sizeof(void*) может давать неправильные значения.

С другой стороны, UINT_PTR определяется с помощью макросов #ifdef и является целымтакие типы, как unsigned long или unsigned __int64, которые в этом случае Intellisense сможет дать правильные размеры.

Компилятор и компоновщик - это программы, которые фактически генерируют код и, таким образом, имеют окончательное мнение о том, что sizeof() на самом деле оценивается в.Вы должны скомпилировать и запустить приведенный выше фрагмент кода и посмотреть фактический результат.Я получаю 8 под 64-битными и 4 под 32-битными.Intellisense - это всего лишь вспомогательный инструмент, который не имеет никакого отношения к окончательному выводу исполняемого файла.


Если у вас нет немедленного доступа к 64-битной машине для тестирования приведенного выше кода, вы можете вместо этогопопробуйте скомпилировать это:

template<unsigned long Size> struct TestSize; // #1
template<> struct TestSize<8> {}; // #2

int main()
{
    // If sizeof(void*) == 8, then #2 will be used.
    // Otherwise, #1 will be used. Since #1 hasn't
    // been completely defined, this line will fail
    // to compile if sizeof(void*) != 8.
    TestSize<sizeof(void*)>();
}

Благодаря магии шаблонов (т.е. специализации шаблонов) приведенный выше фрагмент должен компилироваться только тогда, когда sizeof(void*) равно 8. Вам не нужно запускать полученный исполняемый файл;тот факт, что он компилируется, означает, что sizeof(void*) == 8.

...