Yevgen Muntyan said:
Not if there are no padding bits.
Agreed, but if you need to assume no padding bits, then the
construct isn't useful in a maximal portability sense, is it?
Um, are you saying there is no point in discussion standard C
semantics because on vanilla machine this stuff just works?
I'm saying if you _have_ to make vanilla assumptions to feel
confident about such code, then you've missed the point of
comp.lang.c.
Compilers which follow letter of standard and break existing
code is not exactly news,
You seem to imply that the existing code is correct and the
standard is wrong. In some cases that may well be true, but
I don't see it being the case in the example given.
Fact is, most existing code is just 'lazy', and you seem to
be asking why the standard doesn't allow a particular form
of lazyness explicitly. The real question is, why should it?
even on those "PC" computers.
The OP's example might not be strict enough, but it can
easily check presence of padding bytes.
And what would be the point? Why do you think the 'real problem',
i.e. whatever circumstance has backed the OP into the corner
of wanting to alias an int with a long (or whatever), can't be
better solved using less shakey code that is just as efficient
on vanilla machines?
You missed an important thing here.
That was malloc'ed area,
and its first bytes were set using assignment;
there wasn't a 'real' object declared to have type long
or int.
It became a 'real' object with the assignment [cf effective
type.]
Question is: why is that different from memcpy(),
what do aliasing rules mean.
memcpy isn't about type punning, it's about copying memory
_without_ regard to type.
[Aside: I think it would have been better if C had a separate
type for byte that independant of char, but that wasn't to be.]
double *p = malloc (sizeof (double));
*p = 3.14;
printf("%u\n", *((unsigned*)p));
What is permitted and what isn't?
Good question, but I don't see how bad examples will help you
find good uses.
Then replace double with unsigned long from OP example.
To my eye, this replacement isn't any more useful than the
previous double example.
And may have totally different properties from type punning.
Yes. For a start it's more likely to be well defined, accurate
and useful.
Certainly nothing is wrong with normal conversions.
To play advocate here, there are some problems with characters
and character types to do with aliasing (e.g. explore the value
of é as a constant and as an input character), but the non
character examples so far are based on misguided precept that
it is useful to look at an int as a long. I just don't see the
use.
I think you would do better to explore Christian's optimisation
comments. The standard makes explicit exception for _genuine_
union usages; usages that seem to have been ignored in
preference to pointless discussions on reading longs as ints!
I think you should investigate the possibility of reading ints
as _ints_ through distinct structs sharing common initial
sequences.