GNAT compiler warning: "Constraint_Error will be raised at run time"

I was reading the ebook Advanced Journey with Ada in a section demonstrating conversion between related enumeration types, and I saw that compiling the code for “show_conversion.adb” with GNAT produces the warning message:
show_conversion.adb:9:10: warning: Constraint_Error will be raised at run time [enabled by default]

I wondered: if it can determine that at compile time, why give a warning and not an error?
I found this in the GNAT documentation at AdaCore:

GNAT considers a large number of situations as appropriate for the generation of warning messages. As always, warnings are not definite indications of errors. For example, if you do an out-of-range assignment with the deliberate intention of raising a Constraint_Error exception, then the warning that may be issued does not indicate an error.

I also noticed that there is a compiler switch “-gnatwE” that seems like it would cause all such warnings to be treated as errors.

My question is: why and under what circumstance(s) would an Ada programmer want to “do an out-of-range assignment with the deliberate intention of raising a Constraint_Error exception”?

Thanks!

I don’t remember ever using this in real code.

That said, you’re right about -gnatwE:

$ gnatmake -f -gnatwE show_conversion
gcc -c -gnatwE show_conversion.adb
show_conversion.adb:9:10: error: value not in range of type "Important_Priority" defined at custom_enumerations.ads:5
show_conversion.adb:9:10: error: Constraint_Error would have been raised at run time
gnatmake: "show_conversion.adb" compilation error

which is subtly different from -gnatwe:

$ gnatmake -f -gnatwe show_conversion
gcc -c -gnatwe show_conversion.adb
show_conversion.adb:9:10: warning: value not in range of type "Important_Priority" defined at custom_enumerations.ads:5 [enabled by default]
show_conversion.adb:9:10: warning: Constraint_Error will be raised at run time [enabled by default]
gnatmake: "show_conversion.adb" compilation error
1 Like

Thanks.
I suppose the standard probably says that it raises a Constraint_Error at runtime and someone conceivably might want to rely on that.

Someone else decided to be more decisive on that topic :wink:

procedure Assign_Range is
  subtype T1 is Integer range  0 ..  9;
  subtype T2 is Integer range 10 .. 19;
  x1 : T1;
  x2 : T2 := 10;
  
begin
  x1 := x2;
end;
assign_range.adb: 8:11-11: error in range constraint: value of expression (range: 10 .. 19) is out the destination's range, 0 .. 9
procedure Assign_Singleton is
  x : Positive;
begin
  x := -3;
end;
assign_singleton.adb: 4:10-10: error in range constraint: value of expression (-3) is out the destination's range, 1 .. 9223372036854775807
procedure Index_Range is
  subtype T1 is Integer range  0 ..  9;
  subtype T2 is Integer range 10 .. 19;
  
  a2 : array (T2) of Boolean;
  
  x1 : T1 := 0;
  
begin
  a2 (x1) := True;
end;
index_range.adb: 10:9-9: error in range constraint: value of index (range: 0 .. 9) is out of the array's range, 10 .. 19
procedure Index_Singleton is
  subtype T is Integer range 10 .. 19;
  
  a : array (T) of Boolean;
  
begin
  a (1) := True;
end;
index_singleton.adb: 7:7-7: error in range constraint: value of index (1) is out of the array's range, 10 .. 19
procedure Subtype_Low is
  subtype Wrong is Positive range 0 .. 10;
begin
  null;
end;
subtype_low.adb: 2:43-43: error in range constraint: lower bound, 0, is out of parent type's range, 1 .. 9223372036854775807
procedure Subtype_High is
  subtype Correct is Positive range 1 .. 10;
  subtype Wrong is Correct range 5 .. 11;
begin
  null;
end;
subtype_high.adb: 3:41-41: error in range constraint: higher bound, 11, is out of parent type's range, 1 .. 10