uintptr_t算术运算存未指定行为,如何正确实现指针对齐判断?
指针对齐判断的正确实现方式
原来的is_aligned实现依赖指针转uintptr_t后的模运算,这种方式在多数现代线性地址架构下能正常工作,但在ia32分段内存这类特殊架构中不可靠——因为指针转换为uintptr_t后的值可能包含段选择子等非偏移信息,模运算无法正确反映实际内存位置的对齐状态。
推荐实现:利用编译器内置函数
编译器内置函数会针对目标架构的内存模型做适配,是最可靠的方案:
#include <stdbool.h> #include <stddef.h> #ifdef __GNUC__ static inline bool is_aligned(const void *ptr, size_t align) { return __builtin_is_aligned(ptr, align); } #elif _MSC_VER static inline bool is_aligned(const void *ptr, size_t align) { return _is_aligned(ptr, align); } #else // 仅线性地址架构下可用的兼容 fallback static inline bool is_aligned(const void *ptr, size_t align) { return ((uintptr_t)ptr % align) == 0; } #endif
针对2的幂次对齐的高效实现
如果确定对齐要求是2的幂,可以用位运算实现纯标准C的高效判断(添加静态断言确保参数合法性):
#include <stdbool.h> #include <stddef.h> // 要求:align必须是2的幂 static inline bool is_aligned_power_of_two(const void *ptr, size_t align) { _Static_assert((align & (align - 1)) == 0, "align must be a power of two"); return ((uintptr_t)ptr & (align - 1)) == 0; }
内容的提问来源于stack exchange,提问作者Madagascar
相关产品推荐
相关产品推荐

