最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

delphi - Four byte enum value comparison as signed integer, not as unsigned - Stack Overflow

programmeradmin3浏览0评论

In short, I think, Delphi compares four byte enumeration values as Integer (signed), not as Cardinal (unsigned), as opposed to the documentation:

Finally, if an enumerated type is declared in the {$Z4} state, it is stored as an unsigned double word.

Is there any way to enforce the comparison to be unsigned, without casting the values to Cardinal?

Demo:

program FourByteEnum;
{$APPTYPE CONSOLE}

const
  cvr20100101 = 1001010000;   //* 2010-01-01, 00:00 - timestamp used as version
  cvr20200503 = 2005030000;
  cvr20250303 = 2503030000;

type
{$MINENUMSIZE 4}
  TEnumVersion = (
    evr20100101 = 1001010000,
    evr20200503 = 2005030000,
    evr20250303 = 2503030000
  );

var
  CardinalVersion: Cardinal;
  EnumVersion: TEnumVersion;
begin
  CardinalVersion := cvr20200503;
  writeln('CardinalVersion > cvr20250303 : ', CardinalVersion > cvr20250303); // FALSE
  EnumVersion := evr20200503;
  writeln('EnumVersion > evr20250303 : ', EnumVersion > evr20250303); // TRUE
  writeln('Ord(evr20200503) : ', Ord(evr20200503)); //  2005030000
  writeln('Ord(evr20250303) : ', Ord(evr20250303)); // -1791937296
  readln;
end.

The long story is not so interesting to others, so I left it to the end:

I slowly shoot myself in my foot during the years while maintaining a project. There was a record type with a version: Integer field at the very beginning. The record is binary serialized to disk, and for some reason, I started to use the actual date and time encoded in the version field. Some times ago the encoded value overflowed on MaxInt, and then I changed the type to Cardinal. It was fine.

Now I wanted to refactor the type of the version field to a four byte enum. It has an advantage of type safety, and during the process, the code became non-compilable, so I found some version value comparisons on literals not extracted as version constants. But then I realized the problem above.

So, should I revert the type of the version field to Cardinal, or there is an option to use it as a four byte enum?

发布评论

评论列表(0)

  1. 暂无评论