C++ Undefined behaviour with unions

后端 未结 3 1702
走了就别回头了
走了就别回头了 2020-12-06 19:46

Was just reading about some anonymous structures and how it is isn\'t standard and some general use case for it is undefined behaviour...

This is the basic case:

相关标签:
3条回答
  • 2020-12-06 20:04

    I did not get why you have used float v[2];

    The simple union for a point structure can be defined as:

    union{
    
    struct {
    
        float a;
        float b;
    };
    
    } Point;
    

    You can access the values in unioin as:

    Point.a = 10.5; 
    
    point.b = 12.2; //example
    
    0 讨论(0)
  • 2020-12-06 20:19

    The standard says that reading from any element in a union other than the last one written is undefined behavior. In theory, the compiler could generate code which somehow kept track of the reads and writes, and triggered a signal if you violated the rule (even if the two are the same type). A compiler could also use the fact for some sort of optimization: if you write to a (or x), it can assume that you do not read b (or v[0]) when optimizing.

    In practice, every compiler I know supports this, if the union is clearly visible, and there are cases in many (most?, all?) where even legal use will fail if the union is not visible (e.g.:

    union  U { int i; float f; };
    
    int f( int* pi, int* pf ) { int r = *pi; *pf = 3.14159; return r; }
    
    //  ...
    U u;
    u.i = 1;
    std::cout << f( &u.i, &u.f );
    

    I've actually seen this fail with g++, although according to the standard, it is perfectly legal.)

    Also, even if the compiler supports writing to Point::x and reading from Point::v[0], there's no guarantee that Point::y and Point::v[1] even have the same physical address.

    0 讨论(0)
  • 2020-12-06 20:19

    The standard requires that in a union "[e]ach data member is allocated as if it were the sole member of a struct." (9.5)

    It also requires that struct { float x, y; } and float v[2] must have the same internal representation (9.2) and thus you could safely reinterpret cast one as the other

    Taken together these two rules guarantee that the union you describe will function provided that it is genuinely written to memory. However, because the standard only requires that the last data member written be valid it's theoretically possible to have an implementation that fails if the union is only used as a local variable. I'd be amazed if that ever actually happens, however.

    0 讨论(0)
提交回复
热议问题