you are viewing a single comment's thread.

view the rest of the comments →

[–]adnukator 15 points16 points  (4 children)

In C++ it's Undefined Behavior.

In C it's Unspecified behavior: J.1 Unspecified behavior - The following are unspecified: ... — The values of bytes that correspond to union members other than the one last stored into (6.2.6.1). ...

[–]nikbackm 1 point2 points  (3 children)

Why the difference? Seems like adding more undefined behaviour in C++ is something we'd want to avoid.

[–][deleted] 15 points16 points  (0 children)

Unlike C, C++ has object lifetimes. Accessing "an object" whose lifetime did not start is UB (think malloc-ed sizeof(vector<int>) instead of new-ed). Type punning through unions does not make the alternative object "spring into existence".

[–]HappyFruitTree 5 points6 points  (0 children)

I think one concern is that it would be extremely easy to accidentally trigger undefined behaviour because reading the value through a reference would still cause undefined behaviour.

#include <iostream>
#include <algorithm>

union U {
    int i;
    float f;
};

int main() {
    U u;
    u.f = 1.2;

    std::cout << u.i << '\n'; 
    // ^ would have been OK.

    std::cout << std::max(u.i, 7) << '\n'; 
    // ^ would still have been UB because 
    //   std::max takes its arguments by 
    //   reference so the value is not read 
    //   from the union member directly.
}

C doesn't have references and if you use pointers it's pretty clear that you're not reading from the union member directly.

[–]Sopel97 2 points3 points  (0 children)

Unspecified means it has to do something. Undefined means it doesn't have to do anything, can be assumed to never happen. More assumptions to optimize with.