可以使用std :: uintptr_t避免越界指针算术的未定义行为吗? [英] Can std::uintptr_t be used to avoid undefined behavior of out-of-bounds pointer arithmetic?
问题描述
现在,我们知道执行越界指针算术具有未定义的行为,如本解决方案
是的,这是合法的,但是您必须 reinterpret_cast
完全相同的uintptr_t
值返回到char*
. /p>
(因此,您打算 进行的操作是非法的;也就是说,将不同的值转换回指针.)
5.2.10重新解释演员表
4.指针可以显式转换为足够大的整数类型以容纳它.映射功能是 实施定义.
5.整数类型或枚举类型的值可以显式转换为指针.指针转换 到足够大的整数(如果实现中存在这样的整数)并返回相同的指针类型 将具有其原始值;
(请注意,通常,编译器没有办法知道您减去了一个然后再加回去.)
Now we know that doing out-of-bounds-pointer-arithmetic has undefined behavior as described in this SO question.
My question is: can we workaround such restriction by casting to std::uintptr_t for arithmetic operations and then cast back to pointer? is that guaranteed to work?
For example:
char a[5];
auto u = reinterpret_cast<std::uintptr_t>(a) - 1;
auto p = reinterpret_cast<char*>(u + 1); // OK?
The real world usage is for optimizing offsetted memory access -- instead of p[n + offset]
, I want to do offset_p[n]
.
EDIT To make the question more explicit:
Given a base pointer p
of a char array, if p + n
is a valid pointer, will reinterpret_cast<char*>(reinterpret_cast<std::uintptr_t>(p) + n)
be guaranteed to yield the same valid pointer?
Yes, that is legal, but you must reinterpret_cast
exactly the same uintptr_t
value back to char*
.
(Therefore, what it you're intending to do is illegal; that is, converting a different value back to a pointer.)
5.2.10 Reinterpret cast
4 . A pointer can be explicitly converted to any integral type large enough to hold it. The mapping function is implementation-defined.
5 . A value of integral type or enumeration type can be explicitly converted to a pointer. A pointer converted to an integer of sufficient size (if any such exists on the implementation) and back to the same pointer type will have its original value;
(Note that there'd be no way, in general, for the compiler to know that you subtracted one and then added it back.)
这篇关于可以使用std :: uintptr_t避免越界指针算术的未定义行为吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!