That passage implies that only 1 variant at a time can be active. This in turn implies they share memory.
Not necessarily. Take the following code:
generic TMyUnion<T, U> = record
Selected:Boolean;
first: T;
Second: U;
procedure setSelected(AValue: Boolean);
end;
procedure TMyUnion.setSelected(AValue: Boolean);
begin
if selected=AValue then Exit;
if selected then
begin
Finalize(first);
Initialize(second);
end
else
begin
Finalize(Second);
Initialize(first);
end;
Selected:=AValue;
end;
Now first and second do not share memory, but only ever one will be initialized (and thereby valid to be accessed) while the otherone will not.
Of course such an implementation does not make that much sense, because it's the exact same as if they'd be sharing memory, so basically it's just less efficient, but still it's possible to implement that way..
Also as the comparison to C unions was drawn, I feel the need to point out that the C standard says about unions:
When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that member but do correspond to other members take unspecified values.
So while the overlapping memory allowing to read out the value in different bit reperesentation, this is unspecified behavior and implementation dependent.
It is not a feature of C itself but rather of GCC/Clang/whatever C compiler you use.
(Note that it says "unspecified" and not "undefined", which means it is implementation dependent, while "undefined" would mean it's never correct to read it out)