Re: union members accessed with another member (whose data type requires less space)
On Nov 9, 12:01 pm, Francis Glassborow
<francis.glassbo...@btinternet.com> wrote:
Trying to read a union through a different field than the one by
which it was written is strictly undefined behaviour (there are some
special cases which are exceptions).
I believe this is the intended reading of the C and C++ standards.
However, do note that (nearly) all C and C++ compilers, as an
extension, allow type punning through unions.
This also is related to the standard's "guarantee" that you're allowed
to read and write to any POD through a char* or unsigned char*, except
that this guarantee is never explicitly spelled out, but merely hinted
at in several places.
IIRC, your last option for type punning is memcpy, and I don't recall
if the standard's guarantees are stronger than the char* and unsigned
char* guarantees.
The whole thing is a black art due to the vagueness of the standard,
misinformation, and extensions supported by every compiler (the union
type punning) which many people rely on,but which isn't in the
standard.
PS: Do note that unions are evil because of their associated bug in
the C and C++ standard:
//translation unit 1
void foo(int& x, float& y);
int main()
{
int x = 1;
float y = 2;
foo(x, y);
return x;
}
//translation unit 2
void foo(int& x, float& y) { x = y; }
The strict aliasing rule was intended to allow the compiler to
optimize assuming sufficiently different typed pointers due not alias.
However, a union can make them alias. Thus, a compiler which compiles
separate translation units separately (which is intended by the
standard), and which makes optimization assumptions using strict
aliasing (which is intended by the standard), when compiling a program
using a union, will result in a program broken. In translation unit 1,
the compiler sees the union, and can know that the types int and float
may alias. However, in translation unit 2, the compiler will optimize
assuming that x and y do not alias, and bad things can happen because
they actually do alias. (Or at least for a slightly more complex
function foo bad things may happen.) Moral of this story: don't use
unions, and when you must, don't let references to union members
escape the translation unit (or however it actually works out in
practice, as I am ill informed).
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]