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

  • A+
Category:Languages

Why the following code:

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

Would produce the following compilation error under Delphi XE4 (both win32 and win64):

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

Isn't value $800000 within the range of Cardinal?

 


From a memory perspective, $800000 indeed is within the range of Cardinal.

I thought it the Cardinal($800000) typecast would fix it, but it doesn't.

Delphi XE7 and up actually compile your code correctly.

This also fails up until Delphi XE6 with the same error:

const   CardinalArray: array of Cardinal = [257]; 

I think the reason is that the Delphi compiler sees [257] as a set, despite the left side indicating it is supposed to be an array.

This fails in XE4, but compile fine in XE7 and up:

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 = [     $000000,//0     $800000,//1, compilation error starts with this value     $008000,//2     $808000,//3     $000080,//4     $800080,//5     $008080,//6     $D0D0D0,//7     $3F3F3F,//8     $FF0000,//9     $00FF00,//A     $FFFF00,//B     $0000FF,//C     $FF00FF,//D     $00FFFF,//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. 

Output:

$000000 $800000 $008000 $808000 $000080 $800080 $008080 $D0D0D0 $3F3F3F $FF0000 $00FF00 $FFFF00 $0000FF $FF00FF $00FFFF $FFFFFF 

If you can live with a non-dynamic array, then the below example works in Delphi XE4 (I tested it as far back as Delphi 2007, for XE and earlier, you have to replace System.SysUtils with SysUtils)).

Note the switches:

  • from array of Cardinal to array[0..15] of Cardinal
  • from [ and ] to ( and )
program Cardinals;  {$APPTYPE CONSOLE}  //{$R *.res}  uses   System.SysUtils;  const   ANSICOLORS: array[0..15] of Cardinal = (     $000000,//0     $800000,//1, compilation error starts with this value     $008000,//2     $808000,//3     $000080,//4     $800080,//5     $008080,//6     $D0D0D0,//7     $3F3F3F,//8     $FF0000,//9     $00FF00,//A     $FFFF00,//B     $0000FF,//C     $FF00FF,//D     $00FFFF,//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. 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: