对标准中指针互转性定义的误解
The definition of pointer-interconvertible (https://eel.is/c++draft/basic.compound#6) states that:
如果两个对象是指针互转的,那么它们具有相同的地址,可以通过一个
reinterpret_cast([expr.reinterpret.cast])从指向一个对象的指针得到指向另一个对象的指针。
Yet in reinterpret_cast section https://eel.is/c++draft/expr.reinterpret.cast, there is no mention of it, while it is mentioned for static_cast (https://eel.is/c++draft/expr.static.cast#12):
A prvalue of type “pointer to cv1 void” can be converted to a prvalue of type “pointer to cv2 T”, where T is an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. If the original pointer value represents the address A of a byte in memory and A does not satisfy the alignment requirement of T, then the resulting pointer value ([basic.compound]) is unspecified. Otherwise, if the original pointer value points to an object a, and there is an object b of type similar to T that is pointer-interconvertible with a, the result is a pointer to b. Otherwise, the pointer value is unchanged by the conversion.
在
reinterpret_cast小节 https://eel.is/c++draft/expr.reinterpret.cast 中,没有提及这一点;而在static_cast(https://eel.is/c++draft/expr.static.cast#12) 中有提及:类型为“cv1 void指针”的prvalue可以转换为类型为“cv2 T指针”的prvalue,其中T 是对象类型,cv2的 cv-限定与cv1相同,或比cv1的 cv-限定更高。若原指针值表示内存中某字节地址A,且A 不满足T 的对齐要求,则结果指针值 ([basic.compound]) 未指定。否则,若原指针值指向对象a,且存在类型与T 相似并且与a 互相可指针互转的对象b,则结果是指向b 的指针。否则,指针值在转换中保持不变。
IMHO, it is more meaningful to say that static_cast is allowed for getting a pointer to a pointer-interconvertible type as it basically means that they are pointing to the same object, potentially nested differently.
在我看来,说 static_cast 允许获取一个指向指针互转类型的指针更有意义,因为这基本上意味着它们指向同一个对象,尽管嵌套形式可能不同。
Besides, the fact that using static_cast in this context implies that reinterpret _cast is also valid, through https://eel.is/c++draft/expr.reinterpret.cast#7:
the result is static_cast
(static_cast (v))
此外,在这种上下文中使用 static_cast 还意味着 reinterpret _cast 也是有效的,参见 https://eel.is/c++draft/expr.reinterpret.cast#7:
结果是static_cast
(static_cast (v))
Is it a typo in the standard or is there a rationale to mention reinterpret_cast instead of static_cast in pointer-interconvertible definition?
这是标准中的笔误吗,还是在指针互转的定义中提及 reinterpret_cast 而不是 static_cast 是有其道理的?
解决方案
IMHO, it is more meaningful to say that
static_castis allowed for getting a pointer to a pointer-interconvertible type
在我看来,说 static_cast 可以用来获取一个指向指针互转类型的指针,更有意义。
It is actually not the case
其实并非如此
struct S
{
int i;
int j;
};
static_assert(std::is_pointer_interconvertible_with_class(&S::i));
static_assert(!std::is_pointer_interconvertible_with_class(&S::j));
int main()
{
S s{42, 51};
[[maybe_unused]]int* ok = reinterpret_cast<int*>(&s); // Compiles
[[maybe_unused]]int* ko = static_cast<int*>(&s); // Fails
}