如何在没有警告的情况下在枚举中定义一个非常大的常量?

How to define a very large constant in an enumeration without a warning?

我正在使用 CMCHTPC MediaFoundation headers,它们似乎可以工作,但它们会在几个我想摆脱的地方给出编译器警告。在大多数情况下,罪魁祸首似乎与以下枚举有关:

TMF_Plugin_Type = (
    MF_Plugin_Type_MFT = 0,
    MF_Plugin_Type_MediaSource = 1,
    MF_Plugin_Type_MFT_MatchOutputType = 2,
    MF_Plugin_Type_Other = DWORD(-1)
    );

无论最后一个值如何定义,如 DWORD(-1)DWORD($FFFFFFFF) 或简单地如 $FFFFFFFF,编译器总是回复:

W1012 Constant expression violates subrange bounds

有没有办法在不特别禁止编译器中的警告的情况下修正这个定义? (请注意 {$R-} 不起作用;这会在运行时关闭范围检查,但不会在编译时关闭。)

我想你可以看看 TColorTColorRec 是如何在 System.UITypes 中声明的,并使用 Embarcadero 的经验来声明这样的东西:

  TMF_Plugin_Type = [=10=] .. $FFFFFFFF;

  TMF_Plugin_Type_Rec = record
  const
    MF_Plugin_Type_MFT = 0;
    MF_Plugin_Type_MediaSource = 1;
    MF_Plugin_Type_MFT_MatchOutputType = 2;
    MF_Plugin_Type_Other = TMF_Plugin_Type($FFFFFFFF);
  end;

您可以将其声明为 -1 并给出一个 {$Z4} 来告诉编译器为此枚举使用 4 个字节:

{$Z4}
type
  TMF_Plugin_Type = (
    MF_Plugin_Type_MFT = 0,
    MF_Plugin_Type_MediaSource = 1,
    MF_Plugin_Type_MFT_MatchOutputType = 2,
    MF_Plugin_Type_Other = -1);

它也可以在没有编译器指令的情况下工作。文档说:

To assign an ordinality to a value, follow its identifier with = constantExpression, where constantExpression is a constant expression that evaluates to an integer.

值为-1 的整数在内部表示为 4 个字节。所以无论哪种方式都应该有效。

更新:我重新检查了一下,确实需要编译器指令(除非你在项目选项中设置了类似的选项)。

据我所知,你有两个选择。

  1. 删除 DWORD 转换并将 DWORD(-1) 替换为 -1,如 Uwe 的回答中所述。
  2. 抑制这个特定的编译器警告。您可以使用 {$WARN BOUNDS_ERROR OFF}.
  3. 在代码中执行此操作

选项 1 的缺点是您必须找到每个这样的声明并进行更改。这意味着对第三方库进行大规模更改。如果您希望接受该库的新版本,则必须 re-apply 这些更改。对于某些图书馆来说,这可能会有问题。

所以在我看来,抑制警告可能是更简洁的方法。您可以将抑制指令放在包含文件中,或放在单元的开头。这意味着您对第三方代码所做的更改范围更小。