当我定义一个范围以127结尾的我自己的类型时,编译器不会进行上限检查,它允许变量回绕并在其定义的限制之下变为负数。如果我将范围定义为126,则抛出适当的异常。我在下面列出了这些程序及其输出。
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;
procedure GoodType is
type GOOD_TYPE is range -1..126;
package GOOD_TYPE_IO is new Ada.Text_IO.Integer_IO(GOOD_TYPE);
use GOOD_TYPE_IO;
On_Both1 : GOOD_TYPE := 120;
Index : INTEGER := 0;
begin
for Index in 120..130 loop
On_Both1 := On_Both1 + 1;
Put(Index);
Put(": ");
Put(On_Both1);
New_line;
end loop;
end GoodType;
输出:
gnatmake -f goodtype.adb && ./goodtype
120: 121
121: 122
122: 123
123: 124
124: 125
125: 126
raised CONSTRAINT_ERROR : goodtype.adb:16 range check failed
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;
procedure BadType is
type BAD_TYPE is range -1..127;
package BAD_TYPE_IO is new Ada.Text_IO.Integer_IO(BAD_TYPE);
use BAD_TYPE_IO;
On_Both1 : BAD_TYPE := 120;
Index : INTEGER := 0;
begin
for Index in 120..130 loop
On_Both1 := On_Both1 + 1;
Put(Index);
Put(": ");
Put(On_Both1);
New_line;
end loop;
end BadType;
输出:
gnatmake -f badtype.adb && ./badtype
120: 121
121: 122
122: 123
123: 124
124: 125
125: 126
126: 127
127: -128
128: -127
129: -126
130: -125
答案 0 :(得分:6)
GNAT目前默认禁用溢出检查(在将来的版本中虽然this behavior will change)。
尝试:
gnatmake -gnato -f badtype.adb && ./badtype
126
和127
之间的行为差异显然是因为前者被实现为范围检查(默认情况下启用),后者实现为溢出检查(这是默认情况下禁用)。您可以在两种情况下打印的不同错误消息中看到此信息(使用-gnato
编译时:
raised CONSTRAINT_ERROR : goodtype.adb:16 range check failed
VS
raised CONSTRAINT_ERROR : badtype.adb:16 overflow check failed