Type punning in constant expressions
7.7 [expr.const]
Jason Merrill

Created on 2010-08-31.00:00:00 last changed 96 months ago


Date: 2011-03-15.00:00:00

[Voted into the WP at the March, 2011 meeting as part of paper N3262.]

Date: 2010-11-15.00:00:00

Proposed resolution (November, 2010) [SUPERSEDED]:

Change 7.7 [expr.const] paragraph 2 as follows:

  • an lvalue-to-rvalue conversion...

  • an lvalue-to-rvalue conversion (7.3.2 [conv.lval]) that is applied to a glvalue that refers to a non-active member of a union or a subobject thereof;

  • ...

  • a type conversion from a pointer or pointer-to-member type to a literal type [Note: a user-defined conversion invokes a function —end note] a reinterpret_cast ( [expr.reinterpret.cast]);

[Note: the proposed resolution of issue 1098 edits this bullet in an incompatible fashion.]

Date: 2010-08-31.00:00:00

The status of the following example is not clear:

    union U { float f; unsigned long u; };

    constexpr U u1 = { 1.0 };
    constexpr unsigned long u2 = u1.u;

This might be ill-formed because the aliasing causes undefined behavior, which should make the expression not a constant expression. However, a similar example using a permitted aliasing would presumably be acceptable:

    union U {
        unsigned char c[sizeof(double)];
        double d;
    constexpr U c1u = { 0x12, 0x34 /* etc. */ };
    constexpr double c1 = c1u.d;

One suggestion was that unions should not be considered literal types, but some in the ensuing discussion deemed that excessive. That also would not address similar examples using reinterpret_cast, which is currently also permitted in constant expressions.

Date User Action Args
2014-03-03 00:00:00adminsetstatus: fdis -> c++11
2011-04-10 00:00:00adminsetmessages: + msg3318
2011-04-10 00:00:00adminsetstatus: review -> fdis
2010-11-29 00:00:00adminsetmessages: + msg3079
2010-11-29 00:00:00adminsetstatus: open -> review
2010-08-31 00:00:00admincreate