我正在visual studio pro 2010上编译一个64位的c ++项目,我正在测试指针的大小。它表明sizeof(任何指针)如void *,char *等是4个字节。对于64位系统来说,这似乎是错误的。但是,sizeof(UINT_PTR)为8,对于64位是正确的。
这是我的预处理器定义:_WIN64; _AMD64; _WINDOWS; _DEBUG; _USRDLL;
目标机器是MachineX64(/ MACHINE:X64)。
是否存在定义sizeof()的地方?否则,我怎么才能找出它给我错误尺寸的原因?
感谢。
编辑: 编译器命令行:
/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
答案 0 :(得分:3)
等一下,您是从Intellisense还是从编译器获得sizeof()
值?也就是说,你尝试过编译和运行这样的东西:
#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
。