`reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(&ch) + 1) == &ch +1` 是否有保证?
Is `reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(&ch) + 1) == &ch +1` guaranteed?
我正在编写与对齐相关的代码,并且很惊讶没有标准函数测试给定指针是否正确对齐。
网上好像大部分代码都是用(long)ptr
或者reinterpret_cast<uintptr_t>(ptr)
来测试对齐的,我也用过,但是我想知道使用整型指针是否符合标准.
这里是否有任何系统触发断言?
char ch[2];
assert(reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(&ch[0]) + 1)
== &ch[1]);
回答标题中的问题:没有。
计数器示例:在旧的 Pr1me mini-computer 上,一个普通指针是两个 16 位字。第一个字是 12 位段号、2 个环位和一个标志位(不记得第 16 位)。第二个字是段内的 16 位字偏移量。 char*(因此是 void*)需要第三个词。如果设置了标志位,则第三个字为 0 或 8(是寻址字内的位偏移量)。此类机器的 uintptr_t
需要 uint48_t
或 uint64_t
。无论哪种方式,将 1 加到这样的整数都不会前进到内存中的下一个字符。
能力寻址的机器也可能有比地址 space 大得多的指针,并且没有特别的理由为什么相应整数的最低有效部分应该是 "address" 而不是额外信息的一部分。
当然,在实践中,没有人在为 Pr1me 编写 C++,而且似乎也没有出现处理能力的机器。它适用于所有真实系统 - 但标准并不能保证它。
我正在编写与对齐相关的代码,并且很惊讶没有标准函数测试给定指针是否正确对齐。
网上好像大部分代码都是用(long)ptr
或者reinterpret_cast<uintptr_t>(ptr)
来测试对齐的,我也用过,但是我想知道使用整型指针是否符合标准.
这里是否有任何系统触发断言?
char ch[2];
assert(reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(&ch[0]) + 1)
== &ch[1]);
回答标题中的问题:没有。
计数器示例:在旧的 Pr1me mini-computer 上,一个普通指针是两个 16 位字。第一个字是 12 位段号、2 个环位和一个标志位(不记得第 16 位)。第二个字是段内的 16 位字偏移量。 char*(因此是 void*)需要第三个词。如果设置了标志位,则第三个字为 0 或 8(是寻址字内的位偏移量)。此类机器的 uintptr_t
需要 uint48_t
或 uint64_t
。无论哪种方式,将 1 加到这样的整数都不会前进到内存中的下一个字符。
能力寻址的机器也可能有比地址 space 大得多的指针,并且没有特别的理由为什么相应整数的最低有效部分应该是 "address" 而不是额外信息的一部分。
当然,在实践中,没有人在为 Pr1me 编写 C++,而且似乎也没有出现处理能力的机器。它适用于所有真实系统 - 但标准并不能保证它。