How is a set
organized in memory in Delphi?
What I try to do is casting a simple type to a set type like
var
MyNumber : Word;
ShiftState : TShiftState;
begin
MyNumber:=42;
ShiftState:=TShiftState(MyNumber);
end;
Delphi (2009) won't allow this and I don't understand why. It would make my life a lot easier in cases where I get a number where single bits encode different enum values and I just could cast it like this. Can this be done?
One approach I was going to go for is:
var
ShiftState : TShiftState;
MyNumber : Word absolute ShiftState;
begin
MyNumber:=42;
end;
But before doing this I thought I'd ask for the memory layout. It's more a feeling than knowlege what I am having right now about this.
The computer memory is built to store bit patterns. Not only data but also instructions are bit patterns and these can be stored in memory. In systems software, they are stored in separate segment of memory. And the segments are also divided by data and program type.
A C program memory layout in C mainly comprises six components these are heap, stack, code segment, command-line arguments, uninitialized and initialized data segments. Each of these segments has its own read, write permissions.
“Memory Layout” tells you the size of the installed memory sticks. If the layout is “onboard”, then the RAM is soldered onto the motherboard and cannot be upgraded. For non-Neptun devices, you will need refer to the manual of your laptop and possibly your order confirmation to see how your device is configured.
Memory is laid out in sequential order basically from 0 on up (one byte at a time). Each position in memory has a number (called its address!). The compiler (or interpreter) associates your variable names with memory addresses.
A Delphi set is a bit field who's bits correspond to the associated values of the elements in your set. For a set of normal enumerated types the bit layout is straight-forward:
Things get a bit interesting when you're dealing with a non-contiguous set or with a set that doesn't start at 0. You can do that using Delphi's subrange type (example: set of 3..7
) or using enumerated types that specify the actual ordinal value for the elements:
type enum=(seven=7, eight=8, eleven=11);
EnumSet = set of enum;
In such cases Delphi will allocate the minimum required amount of bytes that will include all required bits, but will not "shift" bit values to use less space. In the EnumSet
example Delphi will use two bytes:
seven
eight
eleven
You can see some tests I did over here: Delphi 2009 - Bug? Adding supposedly invalid values to a set
Tests were done using Delphi 2010, didn't repeat them for Delphi XE.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With