I wanted to make some kind of bit-state options variable, so I can access .STypeIs as 2bit element and STypeIs_Opt1, STypeIs_Opt2 as 1bit elements while they use same place in tagStateInfo Union. So it can be used like this:
' ...........................................................................
Enum SType
Is_Blank = 0
Is_Opt1
Is_Opt2
Is_ERR
End Enum
' ...........................................................................
Union tagStateInfo
Dim As ULongInt Value
Type
Dim As ULongInt Is_New : 1
Dim As ULongInt Is_Base : 1
Dim As ULongInt Is_Complex : 1
Dim As ULongInt Is_Virtual : 1
Dim As ULongInt Is_ExtraOpt1 : 1
Dim As ULongInt Is_ExtraOpt2 : 1
Dim As ULongInt Is_ExtraOpt3 : 1
Dim As ULongInt Is_ExtraOpt4 : 1
Dim As ULongInt Is_ExtraOpt5 : 1
Dim As ULongInt GroupIs_1 : 1
Dim As ULongInt GroupIs_2 : 1
Dim As ULongInt GroupIs_3 : 1
Dim As ULongInt STypeIs : 2 ....>|-> Dim As ULongInt STypeIs_Opt1 : 1
|-> Dim As ULongInt STypeIs_Opt2 : 1
Dim As ULongInt SID : 11
Dim As ULongInt IsNoOp3 : 7
Dim As ULongInt IsNoOp4 : 8
Dim As ULongInt IsNoOp5 : 8
Dim As ULongInt IsNoOp6 : 8
Dim As ULongInt IsNoOp7 : 8
End Type
Declare Operator Cast () Byref As ULongInt
Declare Operator Let (Byref UintVal As ULongInt)
Declare Operator Let (Byref tStateInfo As tagStateInfo)
End Union
' ...........................................................................
Operator tagStateInfo.Cast () Byref As ULongInt
Return This.Value
End Operator
' ...........................................................................
Operator tagStateInfo.Let (Byref UintVal As ULongInt)
This.Value = UintVal
End Operator
' ...........................................................................
Operator tagStateInfo.Let (Byref tStateInfo As tagStateInfo)
This.Value = tStateInfo.Value
End Operator
' ...........................................................................
Dim As tagStateInfo MainState
MainState.Value = 0
MainState.STypeIs = Is_Opt1
Print "STypeIs_Opt1 = ";MainState.STypeIs_Opt1 ' <-- expected "1"
Print "STypeIs_Opt2 = ";MainState.STypeIs_Opt2 ' <-- expected "0"
MainState.STypeIs = Is_Opt2
Print "STypeIs_Opt1 = ";MainState.STypeIs_Opt1 ' <-- expected "0"
Print "STypeIs_Opt2 = ";MainState.STypeIs_Opt2 ' <-- expected "1"
A Type or Union can also contain nested types or unions, allowing data members to be grouped as desired.
Type and Union can be directly nested on condition of alternating their nesting.
Only the main structure (Type or Union) can be named, the others (nested) must be unnamed.
Nested unnamed Type or Union can not have procedure members or static data members (same restriction for local scope named Type/Union).
' ...........................................................................
Enum SType
Is_Blank = 0
Is_Opt1
Is_Opt2
Is_ERR
End Enum
' ...........................................................................
Union tagStateInfo
Dim As ULongInt Value
Type
Dim As ULongInt Is_New : 1
Dim As ULongInt Is_Base : 1
Dim As ULongInt Is_Complex : 1
Dim As ULongInt Is_Virtual : 1
Dim As ULongInt Is_ExtraOpt1 : 1
Dim As ULongInt Is_ExtraOpt2 : 1
Dim As ULongInt Is_ExtraOpt3 : 1
Dim As ULongInt Is_ExtraOpt4 : 1
Dim As ULongInt Is_ExtraOpt5 : 1
Dim As ULongInt GroupIs_1 : 1
Dim As ULongInt GroupIs_2 : 1
Dim As ULongInt GroupIs_3 : 1
Union
Dim As ULongInt STypeIs : 2
Type
Dim As ULongInt STypeIs_Opt1 : 1
Dim As ULongInt STypeIs_Opt2 : 1
End Type
End Union
Dim As ULongInt SID : 11
Dim As ULongInt IsNoOp3 : 7
Dim As ULongInt IsNoOp4 : 8
Dim As ULongInt IsNoOp5 : 8
Dim As ULongInt IsNoOp6 : 8
Dim As ULongInt IsNoOp7 : 8
End Type
Declare Operator Cast () Byref As ULongInt
Declare Operator Let (Byref UintVal As ULongInt)
Declare Operator Let (Byref tStateInfo As tagStateInfo)
End Union
' ...........................................................................
Operator tagStateInfo.Cast () Byref As ULongInt
Return This.Value
End Operator
' ...........................................................................
Operator tagStateInfo.Let (Byref UintVal As ULongInt)
This.Value = UintVal
End Operator
' ...........................................................................
Operator tagStateInfo.Let (Byref tStateInfo As tagStateInfo)
This.Value = tStateInfo.Value
End Operator
' ...........................................................................
Dim As tagStateInfo MainState
MainState.Value = 0
MainState.STypeIs = Is_Opt1
Print "STypeIs_Opt1 = ";MainState.STypeIs_Opt1 ' <-- expected "1"
Print "STypeIs_Opt2 = ";MainState.STypeIs_Opt2 ' <-- expected "0"
MainState.STypeIs = Is_Opt2
Print "STypeIs_Opt1 = ";MainState.STypeIs_Opt1 ' <-- expected "0"
Print "STypeIs_Opt2 = ";MainState.STypeIs_Opt2 ' <-- expected "1"
Note for UDT:
The default-constructor, the copy-constructor, the copy-assignment operator, and the destructor are automatically built by the compiler if they are needed and not explicitly defined by the user.
The implicit copy-assignment operator is already a shallow copy from field to field, so to define your own 'Operator Let (Byref tStateInfo As tagStateInfo)' to overwrite the implicit is useless as it does the same thing.
Thanks! This working but... there a problem or bug or I just not understand how it's should work. I mean - setting main value would not affect/clear any of bits placed after embedded union:
Union tagStateInfo
Dim As ULongInt Value
Type
Dim As ULongInt Is_Opt_01 : 1
Dim As ULongInt Is_Opt_02 : 1
Dim As ULongInt Is_Opt_03 : 1
Dim As ULongInt Is_Opt_04 : 1
Dim As ULongInt Is_Opt_05 : 1
Dim As ULongInt Is_Opt_06 : 1
Dim As ULongInt Is_Opt_07 : 1
Dim As ULongInt Is_Opt_08 : 1
Dim As ULongInt Is_Opt_09 : 1
Dim As ULongInt Is_Opt_10 : 1
Dim As ULongInt Is_Opt_11 : 1
Dim As ULongInt Is_Opt_12 : 1
Dim As ULongInt Is_Opt_13 : 1
Dim As ULongInt Is_Opt_14 : 1
Union
Dim As ULongInt Is_Opt_15_16 : 2
Type
Dim As ULongInt Is_Opt_15 : 1
Dim As ULongInt Is_Opt_16 : 1
End Type
End Union
Dim As ULongInt Is_Opt_17_27 : 11
Dim As ULongInt Is_Opt_28 : 1
Dim As ULongInt IsNoOpt_29 : 1
Dim As ULongInt IsNoOpt_30 : 1
Dim As ULongInt IsNoOpt_31 : 1
Dim As ULongInt IsNoOpt_32 : 1
Dim As ULongInt IsNoOpt_3340 : 8
Dim As ULongInt IsNoOpt_4148 : 8
Dim As ULongInt IsNoOpt_4956 : 8
Dim As ULongInt IsNoOpt_5764 : 8
End Type
End Union
Dim Status As tagStateInfo
Status.Value = 0ULL
Print "Status.Value = 0ULL"
Print "Value = ";Bin(Status.Value,64)
Print "Is_Opt_17_27 = ";Status.Is_Opt_17_27
Print "-----------------------------------------------"
Status.Is_Opt_17_27 = 2047
Print "Status.Is_Opt_17_27 = 2047"
Print "Value = ";Bin(Status.Value,64)
Print "Is_Opt_17_27 = ";Status.Is_Opt_17_27
Print "SizeOf = ";SizeOf(Status)
Print "Len = ";Len(Status)
Print "-----------------------------------------------"
Dim StatusCopy As tagStateInfo
StatusCopy = Status
Print "StatusCopy = Status"
Print "Value = ";Bin(StatusCopy.Value,64)
Print "Is_Opt_17_27 = ";StatusCopy.Is_Opt_17_27
Print "-----------------------------------------------"
StatusCopy.Value = Status.Value
Print "StatusCopy.Value = Status.Value"
Print "Value = ";Bin(StatusCopy.Value,64)
Print "Is_Opt_17_27 = ";StatusCopy.Is_Opt_17_27
Print "-----------------------------------------------"
StatusCopy.Value = 0
Print "StatusCopy.Value = 0"
Print "Value = ";Bin(StatusCopy.Value,64)
Print "Is_Opt_17_27 = ";StatusCopy.Is_Opt_17_27
Print "-----------------------------------------------"
StatusCopy.Value = 0ULL
Print "StatusCopy.Value = 0ULL"
Print "Value = ";Bin(StatusCopy.Value,64)
Print "Is_Opt_17_27 = ";StatusCopy.Is_Opt_17_27
Print "-----------------------------------------------"
StatusCopy.Value = &B0000000000000000000000000000000000000000000000000000000000000000
Print "StatusCopy.Value = &B0000000000000000000000000000000000000000000000000000000000000000"
Print "Value = ";Bin(StatusCopy.Value,64)
Print "Is_Opt_17_27 = ";StatusCopy.Is_Opt_17_27
Print "-----------------------------------------------"
StatusCopy.Value = &B1111111111111111111111111111111111111111111111111111111111111111
Print "StatusCopy.Value = &B1111111111111111111111111111111111111111111111111111111111111111"
Print "***** = ";StatusCopy.Value
Print "Value = ";Bin(StatusCopy.Value,64)
Print "Is_Opt_17_27 = ";StatusCopy.Is_Opt_17_27
Print "-----------------------------------------------"
StatusCopy.Is_Opt_17_27 = 0
Print "StatusCopy.Is_Opt_17_27 = 0"
Print "Value = ";Bin(StatusCopy.Value,64)
Print "Is_Opt_17_27 = ";StatusCopy.Is_Opt_17_27
Print "-----------------------------------------------"
Union test1
Dim As Integer I
Type
Dim As Integer I1 : 1
Dim As Integer I2_3 : 2
Dim As Integer I4 : 1
End Type
End Union
Print Sizeof(test1)
Union test2
Dim As Integer I
Type
Dim As Integer I1 : 1
Union
Dim As Integer I2_3 : 2
Type
Dim As Integer I2 : 1
Dim As Integer I3 : 1
End Type
End Union
Dim As Integer I4 : 1
End Type
End Union
Print Sizeof(test2)
As you have probably already noticed:
- bit field members in a TYPE are packed together, unless the next member is a non-bit field; a nested UNION is considered a non bit field.
- UNION fields must all start at the same address, including any nested TYPE.
Union test3
Dim As Integer I
Type
Dim As Integer I1 : 1
Dim As Integer I2 : 1
Dim As Integer I3 : 1
Dim As Integer I4 : 1
End Type
Type
Dim As Integer padbit_1 : 1
Dim As Integer I2_3 : 2
End Type
End Union
Print "Sizeof(test3) = " & Sizeof(test3)
dim as test3 a, b, c, d, e
a.I1 = 1 : print "I1" , bin( a.I, 8 )
b.I2 = 1 : print "I2" , bin( b.I, 8 )
c.I3 = 1 : print "I3" , bin( c.I, 8 )
d.I4 = 1 : print "I4" , bin( d.I, 8 )
e.I2_3 = 3 : print "I2_3", bin( e.I, 8 )
Union tagStateInfo
Dim As ULongInt Value
Type
Dim As ULongInt Is_Opt_01 : 1
Dim As ULongInt Is_Opt_02 : 1
Dim As ULongInt Is_Opt_03 : 1
Dim As ULongInt Is_Opt_04 : 1
Dim As ULongInt Is_Opt_05 : 1
Dim As ULongInt Is_Opt_06 : 1
Dim As ULongInt Is_Opt_07 : 1
Dim As ULongInt Is_Opt_08 : 1
Dim As ULongInt Is_Opt_09 : 1
Dim As ULongInt Is_Opt_10 : 1
Dim As ULongInt Is_Opt_11 : 1
Dim As ULongInt Is_Opt_12 : 1
Dim As ULongInt Is_Opt_13 : 1
Dim As ULongInt Is_Opt_14 : 1
Dim As ULongInt Is_Opt_15_16 : 2
Dim As ULongInt Is_Opt_17_27 : 11
Dim As ULongInt Is_Opt_28 : 1
Dim As ULongInt Is_NoOpt_29 : 1
Dim As ULongInt Is_NoOpt_30 : 1
Dim As ULongInt Is_NoOpt_31 : 1
Dim As ULongInt Is_NoOpt_32 : 1
Dim As ULongInt Is_NoOpt_33_40 : 8
Dim As ULongInt Is_NoOpt_41_48 : 8
Dim As ULongInt Is_NoOpt_49_56 : 8
Dim As ULongInt Is_NoOpt_57_64 : 8
End Type
Type
Dim As ULongInt padbit_1_14 : 14 '' just used for padding
Dim As ULongInt Is_Opt_15 : 1
Dim As ULongInt Is_Opt_16 : 1
End Type
End Union