為了讓代碼在 32/64 位系統間無縫移植,C 標準庫定義了 size_t 與 ssize_t。本文解析其定義、語義、典型用法及常見誤區。
typedef unsigned int size_t; (32位) / typedef unsigned long size_t; (64位)<stddef.h>、<stdlib.h>、<stdio.h> 等sizeof 運算符返回類型malloc(size_t)、memcpy(void*, void*, size_t)、strlen() 返回值typedef signed int ssize_t; (32位) / typedef signed long ssize_t; (64位)read()/write() 返回 -1 表示失敗)ssize_t,常用 intptr_t 或 long 替代)| 特性 | size_t | ssize_t |
|---|---|---|
| 符號性 | 無符號 | 有符號 |
| 錯誤表示 | 無(通常配合 NULL/錯誤碼) | 負值(如 -1) |
| 適用場景 | 大小、計數、下標 | I/O 返回值、可為負的差值 |
| 可移植性 | C99 標準 | POSIX,Windows 需替代 |
// 陷阱 1:有符號/無符號比較
int len = -1;
size_t n = 10;
if (len < n) ... // len 隱式轉為巨大無符號數,條件為真!
// 陷阱 2:printf 格式
size_t s = sizeof(int);
printf("%zu\n", s); // C99 %zu,非 %d/%u/%ld
// 陷阱 3:64位截斷
long addr = (long)ptr; // 64位指針截斷為 32位
intptr_t addr = (intptr_t)ptr; // 正確:足以容納指針
size_tssize_t (POSIX) / intptr_t (跨平台)ptrdiff_t (C 標準有符號差值類型)%zu (size_t)、%zd (ssize_t/ptrdiff_t)、%td (ptrdiff_t)