P
Pierre Asselin
/* make sure no trap representation involved */
How do you propose to do that ?
/* make sure no trap representation involved */
Where does it say that? Is it aliasing rules or something else?
Because I was suggested here it doesn't matter whether we do
memcpy(&intval, &doubleval, sizeof intval);
or
memcpy(chararray, &doubleval, sizeof intval);
memcpy(&intval, chararray, sizeof intval);
and clearly aliasing rules do not apply to the latter. If it's indeed
aliasing rules, then so be it, it'd be a magic and it'd be fine. In
two posts I was told about trap values, which I take as a possible
explanation of why standard would opt to say something is undefined
(i.e. the reason, the rationale), this is fine. But what exactly place
in the standard says that
unsigned long longval;
unsigned int intval;
/* make sure no trap representation involved */
...
memcpy(&intval, &longval, sizeof intval);
First off, as far as I can tell, none of your examples violate the
aliasing rules. Second, if the change to the bit-representation of an
object does not result in a trap representation, using the value does
not result in undefined behavior. Determining that the result is not
a trap representation is of course not easy to do in a portable way.
Jack said:On 14 Mar 2007 15:10:44 -0700, "Old Wolf" <[email protected]>
wrote in comp.lang.c:
Ok, we've had two long and haphazard threads about unions recently,
and I still don't feel any closer to certainty about what is permitted
and what isn't. The other thread topics were "Real Life Unions"
and "union {unsigned char u[10]; ...} ".
Most of the rambling was caused by the original OP, I think, rather
than the material. I am not criticizing, just observing. [snip]
There is no difference in aliasing in a union than there is via
pointer casting.Sorry if it's something obvious or stupid, but please consider this
(no pointers involved).
You are mistaken, of course there are pointers involved. Just not
pointer objects.
Suppose double is eight bytes big, int is four bytes, there are
no padding bits in int./* (1) get bits from a double and see what happens */
double a = 3.45; unsigned int b;
memcpy(&b, &a, sizeof b);
There are two pointers used in the function call statement. The &
operator generates two addresses, which are passed to memcpy() as
pointers to void.
printf("%u", b);
The behavior is undefined.
/* (2) do same thing using a union */
union U {double a; unsigned int b;} u;
u.a = 3.14;
printf("%u", u.b);
The behavior is undefined.
/* (3) initialize union with memcpy and access its member */
double d;
union U {double a; unsigned int b;} u;
d = 3.14;
memcpy(&u, &d, sizeof d);
printf("%u", u.b);
The behavior is undefined.
Which of three are valid? I think (1) is; (3) maybe; (2) maybe, if
(3) valid and aliasing rules don't work here. If aliasing rules
do apply to (2), then how is first assignment in (2) different
from memcpy() in (3)?
None of the three are valid. The standard does not give you
permission to access an lvalue of type unsigned int after writing some
or all of the bits of a double to it.
Where does it say that?
Is it aliasing rules
Yes
Because I was suggested here it doesn't matter whether we do
memcpy(&intval, &doubleval, sizeof intval);
or
memcpy(chararray, &doubleval, sizeof intval);
memcpy(&intval, chararray, sizeof intval);
and clearly aliasing rules do not apply to the latter.
But what exactly place in the standard says that
unsigned long longval;
unsigned int intval;
/* make sure no trap representation involved */
...
memcpy(&intval, &longval, sizeof intval);
is undefined?
C99 6.5#6 and 6.5#7 .
Those two both have the same effect, if chararray is big enough.
Actually they do. (See below)
It isn't undefined. The behaviour is only undefined if you
subsequently
evaluate the value of 'intval'. The reason it is undefined at that
point
is because of the aliasing rules: you are using an 'unsigned int'
lvalue
to access a bit pattern that is (part of) the bit pattern of a
different
type (namely, unsigned long).
C99 6.5#6 and 6.5#7 .
Those two both have the same effect, if chararray is big enough.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.