pointer interconvertible
#67 ではStrict Aliasing Ruleについて論じたが、以下のキャストはそもそもpointer interconvertibleではないからStrict Aliasing Rule以前の問題だとする指摘がなされた。
class A {};
class B {};
A a;
B* b = reinterpret_cast<B*>(&a);
そもそも元スレのreinterpret_cast式は現在のWDによるといわゆるstrict aliasing ruleで定義されてません。pointer interconvertibleを満たさない場合には意味がすでに必要とされてないため、文面通りの「未定義行為」です。
— g_naggnoyil(gint, gchar **) (@gnaggnoyil) November 27, 2020
https://timsong-cpp.github.io/cppwp/n4861/basic.compound#4.4 4 Two objects a and b are pointer-interconvertible if:
(4.1) they are the same object, or (4.2) one is a union object and the other is a non-static data member of that object ([class.union]), or (4.3) one is a standard-layout class object and the other is the first non-static data member of that object, or, if the object has no non-static data members, any base class subobject of that object ([class.mem]), or (4.4) there exists an object c such that a and c are pointer-interconvertible, and c and b are pointer-interconvertible.
If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a reinterpret_cast. [ Note: An array object and its first element are not pointer-interconvertible, even though they have the same address. — end note ]
cc: @onihusube @yohhoy
異なるオブジェクト型へのポインタ間のキャストは以下で定義されています。https://t.co/QqzA00iyhI
— Kazutoshi SATODA (@k-satoda) November 29, 2020
ここで現れる static_cast について、結果の型の有効なオブジェクトを指すようになる条件が pointer-interconvertible を使って定められています。https://t.co/9O5hRHfjnt
https://timsong-cpp.github.io/cppwp/n4861/expr.reinterpret.cast#7
An object pointer can be explicitly converted to an object pointer of a different type.64 When a prvalue v of object pointer type is converted to the object pointer type “pointer to cv
T”, the result isstatic_cast<cv T*>(static_cast<cv void*>(v)). [ Note: Converting a prvalue of type “pointer toT1” to the type “pointer toT2” (whereT1andT2are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value. — end note ]
- The types may have different cv-qualifiers, subject to the overall restriction that a reinterpret_cast cannot cast away constness. ⮥
https://timsong-cpp.github.io/cppwp/n4861/expr.static.cast#13
A prvalue of type “pointer to cv1
void” can be converted to a prvalue of type “pointer to cv2T”, whereTis an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. If the original pointer value represents the addressAof a byte in memory andAdoes not satisfy the alignment requirement ofT, then the resulting pointer value is unspecified. Otherwise, if the original pointer value points to an object a, and there is an object b of typeT(ignoring cv-qualification) that is pointer-interconvertible with a, the result is a pointer to b. Otherwise, the pointer value is unchanged by the conversion. [ Example:T* p1 = new T; const T* p2 = static_cast<const T*>(static_cast<void*>(p1)); bool b = p1 == p2; // b will have the value true.— end example ]