Search code examples
delphidelphi-7

Delphi Set Invalid Typecast


How do I fix this invalid typecast error? The code works when the set has less than 31 items. Below is the code snippet:

type
  TOptionsSurveyTypes=(
    ostLoadSurvey00,
    ostLoadSurvey01,
    ostLoadSurvey02,
    ostLoadSurvey03,
    ostLoadSurvey04,
    ostLoadSurvey05,
    ostLoadSurvey06,
    ostLoadSurvey07,
    ostLoadSurvey08,
    ostLoadSurvey09,
    ostLoadSurvey10,
    ostEventLog01,
    ostEventLog02,
    ostEventLog03,
    ostEventLog04,
    ostEventLog05,
    ostSagSwell,
    ostTamper,
    ostWaveforms,
    ostDeviceList, 
    ostDeleteData,  
    ostTOUBillingTotal, 
    ostTOUPrevious,
    ostProfileGenericLoadSurvey01,
    ostProfileGenericLoadSurvey02,
    ostProfileGenericLoadSurvey03,
    ostProfileGenericLoadSurvey04,
    ostProfileGenericLoadSurvey05,
    ostProfileGenericLoadSurvey06,
    ostProfileGenericLoadSurvey07,
    ostProfileGenericLoadSurvey08,
    ostProfileGenericLoadSurvey09,
    ostProfileGenericLoadSurvey10,
    ostProfileGenericEventLog01,
    ostProfileGenericEventLog02,
    ostProfileGenericEventLog03,
    ostProfileGenericEventLog04,
    ostProfileGenericEventLog05,
    ostProfileGenericBillingTotal,
    ostProfileGenericPrevious,
    ostProfileGeneric
  );
TOptionsSurveyTypesSet=set of TOptionsSurveyTypes;

function TUserProcessRollback.SurveyRollBack:boolean;
var
  vRollbackDate: TDateTime;
  FOptions: LongWord;
begin
...
  if ostDeleteData in TOptionsSurveyTypesSet(FOptions) then   <-- invalid typecast error here
    vRollbackDate := 0.00
  else
    vRollbackDate := FRollbackDate;

...
end;

When I reduce the set to just less than 32 items and FOptions is declared as DWORD, the code compiles .

Thanks


Solution

  • Your enumerated type has 41 items. Each byte holds 8 bits. To have a set of this enumerated type requires at least 41 bits. The smallest number of bytes necessary to hold 41 bits is 6. So the set type is 6 bytes. To confirm this, you can execute this:

      ShowMessage ( inttostr ( sizeof ( TOptionsSurveyTypesSet ) ) );
    

    A DWORD is 4 bytes, so it cannot be typecast into a type that is 6 bytes. If you declare fOptions to be a type with 6 bytes, your code will compile.

      FOptions: packed array [ 1 .. 6] of byte;
    

    If you reduce the enumerated type to 32 or fewer items, then the set type will be 4 bytes, and so the typecast from DWORD will work.