It seems to be widely accepted that typing via Punning
réinterpréter_cast is somehow forbidden (strictly speaking, "undefined behavior", ie "behavior for which this International Standard does not impose any requirement", with an explicit note stating that implementations can define the behavior) in C ++. Am I wrong to use the following reasoning for not agreeing, And if so, why?
[expr.reinterpret.cast]/ 11 states:
A glvalue expression
T1can be cast to type "reference to
T2"If a pointer-type expression on
T1"Can be explicitly converted to the type" pointer on
réinterpréter_cast. The result refers to the same object as the source glvalue, but with the specified type.[Note:Thisisdirepourleslvaluesuneréférence[Note:Thatisforlvaluesareferencecast[Remarque:c’est-à-direpourleslvaluesuneréférence[ Note:Thatisforlvaluesareferencecast
réinterpréter_casthas the same effect as converting
* reinterpret_castwith the integrated
*operators (and similarly
réinterpréter_cast). – end note]No temporary post is created, no copy is created and the builders or conversion functions are not called.
with the footnote:
75) This is sometimes called a type pun.
/ 11 implicitly implies, for example, the restrictions from / 6 to / 10, but is perhaps the most common use (punning). objects) is discussed in [expr.reinterpret.cast]/ 7:
An object pointer can be explicitly converted to an object pointer of a different type. When a value
vobject pointer type is converted to pointer object type on
CV T", the result is
T1"To type" pointer to
T1 and T2are types of objects and where the alignment requirements of
T2are not more stringent than those of
T1) and return to its original type gives the value of the original pointer. – end note]
Clearly, the goal can not be the conversion to / from pointers or references to
- the example in / 7 clearly shows that
static_castshould be enough in the case of pointers, as do [expr.static.cast]/ 13 and [conv.ptr]/ 2; and
- [conversions to] references to
emptyare prima facie invalid.
Further, [basic.lval]/ 8 states:
If a program tries to access the stored value of an object via a glval value other than one of the following types, the behavior is undefined:
(8.1) the dynamic type of the object,
(8.2) a qualified version CV of the dynamic type of the object,
(8.3) a type similar to the dynamic type of the object,
(8.4) a type that is the signed or unsigned type corresponding to the dynamic type of the object,
(8.5) a type that is the signed or unsigned type corresponding to a qualified version of CV of the dynamic type of the object,
(8.6) a type of aggregate or union that includes one of the above types among its elements or non-static data members (including, on a recurring basis, an element or member of non-static data of a sub-aggregated or confined union),
(8.7) a type which is a type of base class (possibly qualified cv) of the dynamic type of the object,
(8.8) a type of character, an unsigned character or a std :: byte type.
And if we go back to [expr.reinterpret.cast]/ 11 for a moment, we see "The result refers to the same object as a glvalue source, but with the specified type"This reads to me as an explicit statement that the result of
réinterpréter_cast is an lvalue reference to an object Of type
T, to which the access is clearly "by a value glvalue of" "the dynamic type of the object". This sentence also addresses the argument that various paragraphs of [basic.life] apply through the false allegation that the results of these conversions relate to a new object-type
T, whose life has not yet begun, who just happen reside at the same memory address as
It seems absurd to explicitly set such conversions only to ban standard changes. use of results, in particular in the light of footnote 75 noting that [reference] the conversion is "sometimes called type pun. "
Note that my references refer to the final draft publicly available for C ++ 17 (N4659), but that the language in question is little modified from N3337 (C ++ 11) to N4788 (C ++ 20 WD) (link tip will probably reference to subsequent projects over time). In fact, the footnote to [expr.reinterpret.cast]/ 11 is even more explicit in the most recent version:
This is sometimes called a type pun when the result refers to the same object as the source glvalue.