This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-10-26


2882. Unclear treatment of conversion to void

Section: 7.6.1.9  [expr.static.cast]     Status: DR     Submitter: Richard Smith     Date: 2024-04-24

[Accepted as a DR at the June, 2024 meeting.]

The ordering of paragraphs in 7.6.1.9 [expr.static.cast] appears to imply that an attempt is made to form an implicit conversion sequence for conversions to void, possibly considering user-defined conversion functions to void. This is not intended.

Proposed resolution (approved by CWG 2024-05-31):

  1. Move 7.6.1.9 [expr.static.cast] paragraph 6 to before paragraph 4, strike paragraph 5, and adjust paragraph 7:

    Any expression can be explicitly converted to type cv void, in which case the operand is a discarded-value expression (7.2 [expr.prop]). [Note 3: Such a static_cast has no result as it is a prvalue of type void; see 7.2.1 [basic.lval]. —end note] [Note 4: However, if the value is in a temporary object (6.7.7 [class.temporary]), the destructor for that object is not executed until the usual time, and the value of the object is preserved for the purpose of executing the destructor. —end note]

    An Otherwise, an expression E can be explicitly converted to a type T if there is an implicit conversion sequence (12.2.4.2 [over.best.ics]) from E to T, if overload resolution ...

    Otherwise, the static_cast shall perform one of the conversions listed below. No other conversion shall be performed explicitly using a static_cast.

    Any expression can be explicitly converted to type cv void, in which case the operand is a discarded-value expression (7.2 [expr.prop]). [Note 3: Such a static_cast has no result as it is a prvalue of type void; see 7.2.1 [basic.lval]. —end note] [Note 4: However, if the value is in a temporary object (6.7.7 [class.temporary]), the destructor for that object is not executed until the usual time, and the value of the object is preserved for the purpose of executing the destructor. —end note]

    The Otherwise, the inverse of any a standard conversion sequence (7.3 [conv]) not containing an lvalue-to-rvalue (7.3.2 [conv.lval]), array-to-pointer (7.3.3 [conv.array]), function-to-pointer (7.3.4 [conv.func]), null pointer (7.3.12 [conv.ptr]), null member pointer (7.3.13 [conv.mem]), boolean (7.3.15 [conv.bool]), or function pointer (7.3.14 [conv.fctptr]) conversion, can be performed explicitly using static_cast. A program is ill-formed if it uses static_cast to perform the inverse of an ill-formed standard conversion sequence.

  2. Add a new paragraph after 7.6.1.9 [expr.static.cast] paragraph 14:

    A prvalue of type “pointer to cv1 void” can be converted to a prvalue of type “pointer to cv2 T”, ... Otherwise, the pointer value is unchanged by the conversion. [Example 3: ... —end example]

    No other conversion can be performed using static_cast.