应优先使用sysconf(_SC_PAGESIZE),它是POSIX标准、可移植、线程安全的唯一推荐方式;getpagesize()是历史遗留接口,跨平台兼容性差,在musl、Android Bionic等环境下可能返回0或编译失败。

Linux/macOS 下获取系统页面大小,getpagesize() 最快最直接,但跨平台兼容性差;sysconf(_SC_PAGESIZE) 是 POSIX 标准做法,推荐在需要可移植性的场景使用。
为什么 getpagesize() 有时返回 0 或不准确
getpagesize() 是 glibc 提供的封装函数,底层依赖内核 getpagesize(2) 系统调用。但在某些嵌入式环境、musl libc(如 Alpine Linux)或旧版 macOS 上,该函数可能未实现或返回 0 —— 这不是 bug,而是 libc 选择不提供 fallback。
- Alpine Linux 默认用 musl,
getpagesize()返回 0;必须改用sysconf(_SC_PAGESIZE) - macOS 12+ 已弃用
getpagesize()的 man page,虽仍可用,但文档明确建议用sysconf - 若在静态链接或 stripped 二进制中调试,
getpagesize()符号可能被优化掉,而sysconf更稳定
sysconf(_SC_PAGESIZE) 的正确用法和陷阱
sysconf() 是 POSIX.1 标准接口,返回长整型,出错时返回 -1 并设置 errno。它不保证总是成功,尤其在容器或 chroot 环境中,/proc 不可用时可能失败。
- 必须包含
,且定义_POSIX_C_SOURCE宏(GCC 下加-D_POSIX_C_SOURCE=200809L或在代码开头#define _POSIX_C_SOURCE 200809L) - 返回值是
long,需转为size_t或int时注意符号扩展(如在 64 位系统上long是 8 字节,但页面大小永远 ≤ 64KiB) - 不要忽略错误检查:
long ps = sysconf(_SC_PAGESIZE); if (ps == -1) { /* handle error */ }
实际项目中怎么选:一个安全的跨平台宏
多数 C++ 项目不需要运行时动态探测页面大小——编译时已知目标平台,更稳妥的做法是预定义 + fallback。
- Linux/macOS:优先
sysconf(_SC_PAGESIZE),失败则 fallback 到getpagesize()(仅 glibc 环境) - Windows:不用这两个,应调用
GetSystemInfo()获取dwPageSize,或用__builtin_assume+ 编译器内置常量(Clang/GCC 支持__builtin_constant_p) - 简明安全写法(Linux/macOS):
#include <unistd.h> #include <cstdlib><p>constexpr size_t get_page_size() {</p> <h1>if defined(<strong>linux</strong>) || defined(<strong>APPLE</strong>)</h1> <pre class="brush:php;toolbar:false;">long ps = sysconf(_SC_PAGESIZE); return (ps > 0) ? static_cast<size_t>(ps) : 4096;</size_t>else
return 4096; // conservative default
endif
}
真正容易被忽略的是:页面大小不等于内存分配粒度(如 mmap 的 addr 对齐要求)、也不等于 TLB 页表项大小(大页如 2MiB 需显式启用)。拿 getpagesize() 或 sysconf 返回的值去对齐 malloc 内存,基本没意义——那是 aligned_alloc 或 posix_memalign 的事。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











