Originally Posted by
Sebastiani
this is clearly unsafe since B::a may or may not be aligned at the base address of the outer object.
Actually, since both A and B are PODs here, B::a is guaranteed to have the same starting address as the containing B instance, and the cast is safe, with predictable results.
The same cannot be said for non-PODs.
Originally Posted by
Soma
on the other hand, casting back and forth between distinct pointers types should be completely safe as long as they aren't dereferenced (in the truest sense of the word). and if this isn't guaranteed by the standard then why not?
The round-trip A->B->A is guaranteed if the alignment requirements for B aren't greater than those for A. For example, if Bs always have to be aligned at 4 bytes and so do As, it's safe, but if As only need to be aligned at 2 bytes or need not be aligned at all, it isn't. Since your null_t has no members, it has no alignment requirement, and the cast to any type that does, and back, will not round-trip.
Again, if you are going to go, go all out; return (0) and check against (0). This would completely solve '1' and '2' as offered by CornedBee.
No. Dereferencing the null pointer to get a reference is explicitly mentioned to be undefined. It doesn't matter that no hardware dereferencing actually takes place. A compiler is allowed to reject the code if it can prove you're dereferencing 0.
Here's something you can do with pointers that you can't do with null references:
Code:
foo *fn1(); // Might return null.
foo &fn2(); // Might return null.
if(foo *pfoo = fn1()) {
// pfoo isn't null. If fn1 returns null, the block isn't entered. pfoo isn't visible outside the block.
// It's not possible to access a null pfoo.
}
if(foo &rfoo = fn2()) {
// If foo has no boolean conversion, this fails to compile.
// If foo has a boolean conversion and fn2 returns an object, this conversion will be used to
// decide whether the block is entered. Unless the conversion determines a "bad" state,
// this is not useful. (And if it does, then returning null is not useful.)
// If foo has a boolean conversion and fn2 returns null, the program will crash! Or, worse,
// because it's not a true null it may do something very silly.
}
Don't break the language rules!