Constant `array of cardinal` produces error 'Constant expression violates subrange bounds"
You are using a feature introduced in XE7.
Declaring a dynamic array constant.
Dynamic arrays_Delphi xe7 and
String-Like_Operations_Supported_on_Dynamic_Arrays
In XE4, this is evaluated as a set, where the ordinality cannot exceed 255.
Hence the error E1012 Constant expression violates subrange bounds
Fix it by declaring:
const
ANSICOLORS: array[0..15] of cardinal = (
$000000,//0
$800000,//1,
$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
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
toarray[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.