is identical with:
struct one *o = (struct one *) fred;
struct two *ptr2 = (struct two*) (o + 1);
Modulo your typos, which I've fixed above, yes.
When you put your [compiler] in the sharpest warning level you [need]
the casting. ALL warnings are really helpful! But when you [know]
exactly what you [are doing] you can avoid the warning by saying [to]
the compiler: be [quiet], I know what I [am doing].
While this is also true, I don't see what casting has to do with
anything. As you said, the two code samples are basically equivalent.
Neither one contains any compiler error. Both contain undefined
behavior.
long x = ptr2->l;
================
Code equivalent to the above will generate an alignment fault on some
architectures.
Never - except
struct two t2[2];
t2[1].l = 0;
gives the same exception - but then your compiler is buggy.
That doesn't make any sense. My compiler is *not* buggy, and I don't
see any reason to suspect that Jack's is, either. The code above,
using t2[1], exhibits perfectly well-defined behavior. The code
that Jack posted, and the equivalent code that you posted, using
ptr2, exhibits undefined behavior.
Each struct is defined on an aligned address - [always]!
This is patently false. Consider again:
struct foo { char c; };
struct bar { int i; };
On many architectures, 'foo' will have an alignment restriction
of 1 or 2 bytes, and 'bar' will have an alignment restriction of
4 bytes. This is not theoretical.
You must do some
undefined pointer arithmetic to get an misaligned pointer.
True, but vacuous. Consider:
char c;
void *p = &c;
int *i = p;
Of course this is "undefined", and it's "pointer arithmetic",
but I don't think it's meaningful to call it "undefined pointer
arithmetic", since each operation is perfectly reasonable in
and of itself.
Replace the above with
struct foo c;
void *p = &c;
struct bar *i = p;
and you have the exact same problem - undefined behavior that
your average compiler won't be able to catch.
Indeed.
-Arthur