"Сюрпризы" численных типов
Достаточно часто распространены случаи, когда программист, который только начинает знакомиться с языком программирования Ада, попадается в ловушку численных типов.
Рассмотрим следующий пример программы:
with Ada.Text_IO;
procedure Numeric is type My_Integer_Type is new Integer range 1..5; My_Integer_Variable : My_Integer_Type := 2; Standard_Integer_Variable : Integer := 2; Result_Variable : Integer; begin Result_Variable := Standard_Integer_Variable * My_Integer_Variable; Ada.Text_IO.Put_Line ("Result_Variable = " & Result_Variable'Img); end Numeric; |
Хотя на первый взгляд все выглядит достаточно логично, данная программа компилироваться не будет.
Причиной ошибки будет тип My_Integer_Type, или точнее - отсутствие описания знака операции умножения "*", который одновременно воспринимает левый операнд, стандартного целочисленного типа Integer, и правый операнд, целочисленного типа My_Integer_Type.
Такое поведение компилятора Ады продиктовано требованиями строгой именной эквивалентности типов.
Чтобы решить возникшую проблему, необходимо описать тип My_Integer_Type в самостоятельном пакете и описать соответствующие знаки операций, которые будут допустимы для использования над значениями данного целочисленного типа.
Вполне естественно, что подобный вариант решения проблемы малопривлекателен, а подобная строгость типизации может показаться чрезмерной даже приверженцам языка Паскаль.
Следует заметить, что существует альтернативный вариант, который гораздо проще и удобнее.
Следует описать My_Integer_Type не как тип, производный от типа Integer, а как подтип типа Integer с ограниченным диапазоном значений.
После таких изменений наш пример программы будет иметь слудующий вид:
with Ada.Text_IO;
procedure Numeric is subtype My_Integer_Type is Integer range 1..5; My_Integer_Variable : My_Integer_Type := 2; Standard_Integer_Variable : Integer := 2; Result_Variable : Integer; begin Result_Variable := Standard_Integer_Variable * My_Integer_Variable; Ada.Text_IO.Put_Line ("Result_Variable = " & Result_Variable'Img); end Numeric; |
В данном случае процедура Numeric будет успешно откомпилирована компилятором.