在 C 中,如果一定数量的尾随位为零,则指针与特定对齐。这需要提取指针的位,尽管只有有限数量的尾随位。最明显的方法是将指针投射到
uintptr_t
并使用位掩码:
void *my_ptr;
bool aligned_to_16 = (uintptr_t)my_ptr & 15;
但是,C 标准不需要
uintptr_t
,因为这是可选类型。如果指针太大而无法容纳整数,则可能会出现这种情况。然而,“应该”并不重要,因为无论如何我们只关心尾随位。那么如果我只是投射到 unsigned char
或 int
呢?好吧,根据this答案,这仍然是未定义的行为,即使我们不关心会导致值不适合的前导位:
据我所知,指针到不同类型指针的所有其他转换都是未定义的行为。特别是,如果您没有转换为 char 或足够大的整数类型,则将指针转换为不同的指针类型可能始终是 UB - 即使没有取消引用它。我找不到任何符合故障安全标准的方法来提取指针的实际尾随位,例如测试指针对齐,该方法不会调用任何可选功能或实现定义/未指定/未定义的行为。但除了使用
snprintf()
格式说明符执行
%p
并解析结果之外,实际上还有其他方法吗?另一方面,该标准未能强制要求所有实现的行为方式对于 99% 的实现而言都是通用的,但这并不意味着编译器编写者通常不应该这样做,从而将偏差限制在那些具有
明显或有记录的实现中和令人信服的理由。这也不意味着程序员应该克服困难来适应相反的行为,除非他们需要以此类行为合理的实现为目标,或者其作者将标准允许这种偏差视为其本身的合理性。