常量“基数数组”产生错误“常量表达式违反子范围边界”

Constant `array of cardinal` produces error 'Constant expression violates subrange bounds"

为什么是下面的代码:

const
  ANSICOLORS: array of cardinal = [
    [=10=]0000,//0
    0000,//1, compilation error starts with this value
    [=10=]8000,//2
    8000,//3
    [=10=]0080,//4
    0080,//5
    [=10=]8080,//6
    $D0D0D0,//7
    F3F3F,//8
    $FF0000,//9
    [=10=]FF00,//A
    $FFFF00,//B
    [=10=]00FF,//C
    $FF00FF,//D
    [=10=]FFFF,//E
    $FFFFFF];//F

在DelphiXE4(win32和win64)下会产生如下编译错误:

[dcc32 Error] Debug.pas(66): E1012 Constant expression violates subrange bounds

0000不在Cardinal范围内吗?

从内存的角度来看,0000确实在Cardinal的范围内。

我认为 Cardinal(0000) 类型转换会修复它,但它没有。

Delphi XE7 及更高版本实际上可以正确编译您的代码。

这在 Delphi XE6 之前也失败,并出现相同的错误:

const
  CardinalArray: array of Cardinal = [257];

我认为原因是 Delphi 编译器将 [257] 视为 set,尽管左侧表明它应该是 array

这在 XE4 中失败,但在 XE7 及更高版本中编译正常:

program Cardinals;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

const
  CardinalArray: array of Cardinal = [257]; // fails until Delphi XE4 with "E1012 Constant expression violates subrange bounds"

const
  ANSICOLORS: array of Cardinal = [
    [=11=]0000,//0
    0000,//1, compilation error starts with this value
    [=11=]8000,//2
    8000,//3
    [=11=]0080,//4
    0080,//5
    [=11=]8080,//6
    $D0D0D0,//7
    F3F3F,//8
    $FF0000,//9
    [=11=]FF00,//A
    $FFFF00,//B
    [=11=]00FF,//C
    $FF00FF,//D
    [=11=]FFFF,//E
    $FFFFFF];//F

var
  AnsiColor: Cardinal;

begin
  try
    for AnsiColor in AnsiColors do
      Writeln(Format('$%6.6x', [AnsiColor]));
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

输出:

[=12=]0000
0000
[=12=]8000
8000
[=12=]0080
0080
[=12=]8080
$D0D0D0
F3F3F
$FF0000
[=12=]FF00
$FFFF00
[=12=]00FF
$FF00FF
[=12=]FFFF
$FFFFFF

如果您可以使用非动态数组,那么下面的示例可以在 Delphi XE4 中运行(我早在 Delphi 2007 年就对其进行了测试,对于 XE 和更早版本,您有将 System.SysUtils 替换为 SysUtils))。

注意开关:

  • array of Cardinalarray[0..15] of Cardinal
  • []()
program Cardinals;

{$APPTYPE CONSOLE}

//{$R *.res}

uses
  System.SysUtils;

const
  ANSICOLORS: array[0..15] of Cardinal = (
    [=13=]0000,//0
    0000,//1, compilation error starts with this value
    [=13=]8000,//2
    8000,//3
    [=13=]0080,//4
    0080,//5
    [=13=]8080,//6
    $D0D0D0,//7
    F3F3F,//8
    $FF0000,//9
    [=13=]FF00,//A
    $FFFF00,//B
    [=13=]00FF,//C
    $FF00FF,//D
    [=13=]FFFF,//E
    $FFFFFF);//F

var
  AnsiColor: Cardinal;

begin
  try
    for AnsiColor in AnsiColors do
      Writeln(Format('$%6.6x', [AnsiColor]));
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

您正在使用 XE7 中引入的功能。

正在声明动态数组常量。

Dynamic arrays_Delphi xe7

String-Like_Operations_Supported_on_Dynamic_Arrays


在 XE4 中,这是作为一个集合计算的,其中序数不能超过 255。

因此错误 E1012 Constant expression violates subrange bounds

通过声明修复它:

const
  ANSICOLORS: array[0..15] of cardinal = (
    [=10=]0000,//0
    0000,//1, 
    [=10=]8000,//2
    8000,//3
    [=10=]0080,//4
    0080,//5
    [=10=]8080,//6
    $D0D0D0,//7
    F3F3F,//8
    $FF0000,//9
    [=10=]FF00,//A
    $FFFF00,//B
    [=10=]00FF,//C
    $FF00FF,//D
    [=10=]FFFF,//E
    $FFFFFF);//F