Real case that will break when access non-active union members?

Viewed 62

According to cppreference and Purpose of Unions in C and C++, the code below is UB:

// convert char[8] to uint64_t
uint64_t convert(char c[8]) {
  union{
    uint64_t v;
    char c[8];
  } u;
  for(int i = 0; i < 8; i++) {
    u.c[i] = c[i];
  }
  return u.v;
}

// another example
union U {
  uint64_t v;
  struct{
    uint32_t l;
    uint32_t h;
  }d;
};

uint64_t setlow(uint64_t v, uint32_t l) {
  U u{v};
  u.d.l = l;
  return u.v;
}

However, even though it's UB, this kind of usage gives much convenience and I find it actually works for most compilers(GCC/Clang). So I want to know is there any compiler/implementation in practice that will make the code above break?

1 Answers

The reason the language hasn’t blessed the compiler extension (based on questionable C wording) is that it doesn’t fit with the rest of the language. Consider:

union U {
    float f;
    int i;
    int operator()();
};
static int putget(float &f,int &i) {
    i=0;
    f=1;
    return i;
}
int U::operator()() {return putget(f,i);}

With the function definition immediately available, GCC and Clang elide the store to i, and yet they return 0 as if that store had not only happened but wasn’t dead.

Related