|
MSVC(VC++)下各类常用类型的“占用字节数”按平台整理成精确对照表,并补充易混淆点与自检方法。Windows 的 64 位 ABI 采用 LLP64(long 仍是 4 字节,指针/size_t 等是 8 字节),x64 与 ARM64 在大小上相同。 核心结论(LLP64 模型)- 32 位(Win32/x86):指针与 size_t 4 字节
- 64 位(Win64/x64/ARM64):指针与 size_t 8 字节
- long 在 MSVC 下无论 32/64 位都是 4 字节
- long double 在 MSVC 下与 double 相同,均为 8 字节
- wchar_t 在 MSVC 下为 2 字节(UTF-16)
基本整型与浮点- 列“x86”为 32 位;列“x64/ARM64”为 64 位(两者一致)
- 单位:字节
[td]| 类型 | x86 | x64/ARM64 | bool | 1 | 1 | char | 1 | 1 | signed char | 1 | 1 | unsigned char | 1 | 1 | short | 2 | 2 | unsigned short | 2 | 2 | int | 4 | 4 | unsigned int | 4 | 4 | long | 4 | 4 | unsigned long | 4 | 4 | long long | 8 | 8 | unsigned long long | 8 | 8 | __int8 | 1 | 1 | __int16 | 2 | 2 | __int32 | 4 | 4 | __int64 | 8 | 8 | float | 4 | 4 | double | 8 | 8 | long double (MSVC) | 8 | 8 | __int128(MSVC) | 不支持 | 不支持 |
备注: - MSVC 不提供原生 __int128;clang-cl 可能支持但不属于 MSVC。
- char 的有符号/无符号取决于编译选项;MSVC 默认为 signed char(可用 /J 改为 unsigned)。
字符与文本相关[td]| 类型 | x86 | x64/ARM64 | 说明 | wchar_t | 2 | 2 | UTF-16 code unit | char8_t | 1 | 1 | C++20 | char16_t | 2 | 2 | C++11/14+ | char32_t | 4 | 4 | C++11/14+ | TCHAR | 1 | 2 | 取决于是否定义 UNICODE | WCHAR | 2 | 2 | WinAPI 基本类型 | CHAR | 1 | 1 | WinAPI 基本类型 |
提示: - MSVC 下 /Zc:wchar_t 启用原生 wchar_t(默认已启用)。
- TCHAR 受是否定义 UNICODE 影响:ANSI 构建为 1 字节,Unicode 构建为 2 字节。
指针与与平台相关类型[td]| 类型 | x86 | x64/ARM64 | 说明 | void*(任意对象指针) | 4 | 8 | 指针大小 | 函数指针 | 4 | 8 | 与对象指针同大小 | size_t | 4 | 8 | 对象大小/计数类型 | ptrdiff_t | 4 | 8 | 指针差值类型 | intptr_t | 4 | 8 | 可容纳指针的整数 | uintptr_t | 4 | 8 | 可容纳指针的无符号整数 | time_t | 4 或 8 | 8 | 见下方说明 |
关于 time_t(重要): - 64 位(x64/ARM64):time_t 固定为 8 字节。
- 32 位(x86):在较新的 MSVC/UCRT 中默认也为 8 字节;如果定义了 _USE_32BIT_TIME_T 则为 4 字节。旧版 VC(VS2003 及更早)默认是 4 字节。
常见 Win32 基本类型(Windows SDK)[td]| 类型 | 大小(x86 / x64/ARM64) | 说明 | BYTE | 1 / 1 | unsigned char | WORD | 2 / 2 | 16-bit 无符号 | DWORD | 4 / 4 | 32-bit 无符号 | DWORD64 | 8 / 8 | 64-bit 无符号 | BOOL | 4 / 4 | WinAPI 布尔(与 C++ bool 不同大小) | BOOLEAN | 1 / 1 | UCHAR, 一般出现在 NT 内核风格接口 | WCHAR | 2 / 2 | UTF-16 | ULONG | 4 / 4 | 32-bit 无符号长整型 | ULONGLONG | 8 / 8 | 64-bit 无符号长长 | SIZE_T | 4 / 8 | 指针大小相关 | SSIZE_T | 4 / 8 | 有符号 SIZE_T | INT_PTR | 4 / 8 | 指针大小的有符号整数 | UINT_PTR | 4 / 8 | 指针大小的无符号整数 | LONG_PTR | 4 / 8 | 指针大小的长整型 | ULONG_PTR | 4 / 8 | 指针大小的无符号长整型 | WPARAM | 4 / 8 | UINT_PTR | LPARAM | 4 / 8 | LONG_PTR | LRESULT | 4 / 8 | LONG_PTR | HANDLE/HWND… | 4 / 8 | 指针大小类型 | SOCKET | 4 / 8 | typedef 为 UINT_PTR(指针大小) | FILETIME | 8 / 8 | 两个 DWORD 组成 | LARGE_INTEGER | 8 / 8 | 64-bit 联合 | ULARGE_INTEGER | 8 / 8 | 64-bit 联合 | C 标准定宽整数 <cstdint>(MSVC 上的映射)[td]| 类型 | x86 | x64/ARM64 | int8_t | 1 | 1 | uint8_t | 1 | 1 | int16_t | 2 | 2 | uint16_t | 2 | 2 | int32_t | 4 | 4 | uint32_t | 4 | 4 | int64_t | 8 | 8 | uint64_t | 8 | 8 | intptr_t | 4 | 8 | uintptr_t | 4 | 8 | size_t | 4 | 8 | ptrdiff_t | 4 | 8 | 易混淆与补充说明- long 在 Windows/MSVC 上总是 4 字节,即使在 64 位;不要套用 Linux/Unix 上的 LP64(那里的 long 是 8 字节)。
- long double 在 MSVC 上与 double 相同(8 字节);如需 80/128-bit 扩展精度,需依赖第三方库或编译器扩展(MSVC 不原生提供)。
- TCHAR 受是否定义 UNICODE 影响:ANSI 构建 1 字节,Unicode 构建 2 字节。
- char 的有无符号属性会影响表达式提升与 I/O;MSVC 默认 signed(可用 /J 改为 unsigned)。
- 结构体大小不仅与成员大小有关,还与对齐(alignment)与打包(#pragma pack)相关;本文为“类型本身”大小,非结构体排列后的占用。
一段自检代码(建议在本机确认)可建一个小控制台程序,编译一次 x86、一次 x64,对照输出: - #include <iostream>
- #include <cstdint>
- #include <cstddef>
- #include <cwchar>
- #include <windows.h>
- #include <time.h>
- #define SHOW(T) std::wcout << L#T L": " << sizeof(T) << L" bytes\n"
- int main() {
- std::wcout << L"Fundamental:\n";
- SHOW(bool); SHOW(char); SHOW(signed char); SHOW(unsigned char);
- SHOW(short); SHOW(unsigned short);
- SHOW(int); SHOW(unsigned int);
- SHOW(long); SHOW(unsigned long);
- SHOW(long long); SHOW(unsigned long long);
- SHOW(float); SHOW(double); SHOW(long double);
- std::wcout << L"\nChars:\n";
- SHOW(wchar_t); SHOW(char8_t); SHOW(char16_t); SHOW(char32_t);
- std::wcout << L"\nPointers & size types:\n";
- SHOW(void*); SHOW(size_t); SHOW(ptrdiff_t); SHOW(intptr_t); SHOW(uintptr_t); SHOW(time_t);
- std::wcout << L"\nWindows types:\n";
- SHOW(BOOL); SHOW(BOOLEAN); SHOW(BYTE); SHOW(WORD); SHOW(DWORD); SHOW(DWORD64);
- SHOW(WCHAR); SHOW(TCHAR); SHOW(SIZE_T); SHOW(SSIZE_T); SHOW(INT_PTR); SHOW(UINT_PTR); SHOW(LONG_PTR); SHOW(ULONG_PTR);
- SHOW(WPARAM); SHOW(LPARAM); SHOW(LRESULT); SHOW(HANDLE); SHOW(HWND); SHOW(SOCKET);
- SHOW(FILETIME); SHOW(LARGE_INTEGER); SHOW(ULARGE_INTEGER);
- return 0;
- }
复制代码可选参数: - 强制 32 位:添加项目平台 Win32 或使用编译器 x86 工具集
- 强制 64 位:添加 x64/ARM64 平台
- 若需验证 32 位下 4/8 字节的 time_t,切换是否定义 _USE_32BIT_TIME_T
|