From bobduff@world.std.com Wed Apr 17 10:11:20 1996 Return-Path: Received: from inmet.camb.inmet.com by dsd.camb.inmet.com (4.1/SMI-4.1) id AA06582; Wed, 17 Apr 96 10:11:20 EDT Received: from sw-eng.falls-church.va.us (ns1.sw-eng.falls-church.va.us) by inmet.camb.inmet.com (4.1/SMI-4.1) id AA11839; Wed, 17 Apr 96 10:11:31 EDT Received: from europe.std.com by sw-eng.falls-church.va.us (8.7.1/) id OAA28499; Wed, 17 Apr 1996 14:10:37 GMT Received: from world.std.com by europe.std.com (8.7.5/BZS-8-1.0) id KAA21068; Wed, 17 Apr 1996 10:10:49 -0400 (EDT) Received: by world.std.com (5.65c/Spike-2.0) id AA10215; Wed, 17 Apr 1996 10:10:54 -0400 Date: Wed, 17 Apr 1996 10:10:54 -0400 From: bobduff@world.std.com (Robert A Duff) Message-Id: <199604171410.AA10215@world.std.com> To: jb@ddci.dk, ada-comment@sw-eng.falls-church.va.us, dewar@gnat.com, banner@gnat.com In-Reply-To: <9604161009.AA19353@sparc7.ddci.dk> (jb@ddci.dk) Subject: Size program !topic Size program !reference RM95-13.3(55) !from Bob Duff <> !discussion Joergen Bundgaard said: > However, may I suggest that the vendors be given a chance to provide > their input in standard way, for example by compiling and running a > standard program written by YOU to print out the information you need, > for example: OK, good idea. Here's a program. It prints out various Sizes of various subtypes. Two programs, actually: one for Ada 83 and one for Ada 95. The code that is Ada-95-specific is split out into a separate package. So, you can run the Size_Test_83 program on an Ada 83 compiler, and you can run the Size_Test_95 program on an Ada 95 compiler. It would be nice to get some feedback from compiler vendors, as to what existing Ada 83 and/or Ada 95 compilers do for these programs. The "expected results" in the following are (barring typos) my own personal opinion of what an Ada 95 compiler ought to do. This is pretty close to what the RM requires, or should require, but I might have overstepped the bounds in some cases. If your compiler disagrees, let us know whether you think the test is wrong, or the compiler. If your compiler gives compile-time error messages, then please comment out the offending part of the program, and try again. Also, let us know whether you think the compiler is right to give the error message. I threw this together pretty quickly. I hereby apologize in advance for any typos in expected results, or any other bugs. - Bob The program consists of the following files (GNAT naming conventions), which are concatenated together below: size_test_utils.ads size_test_utils.adb size_test_83_pkg.ads size_test_83_pkg.adb size_clause_83_pkg.ads size_test_95_pkg.ads size_test_95_pkg.adb size_test_83.adb size_test_95.adb with System; use System; package Size_Test_Utils is procedure Put_Line(S: String); -- Print a line with line number. procedure Heading(S: String); -- Print a heading with blank lines around it. type Size_In_Bits is range 0..Max_Int; function Img(X: Size_In_Bits) return String; -- Shorthand for Size_In_Bits'Image. procedure Check(Subtype_Name: String; Subtype_Size: Size_In_Bits; Expected_Size: Size_In_Bits); -- Prints out the subtype's Size. If Subtype_Size /= Expected_Size, -- notes that fact. procedure Check(Subtype_Name: String; Subtype_Size: Size_In_Bits); -- Same as previous, but used when there's no particular expected size. -- The following functions are the same as the corresponding -- procedures. They return an irrelevant value. The purpose -- is to be able to call those procedures in a declaration -- context. function Heading(S: String) return Boolean; function Check(Subtype_Name: String; Subtype_Size: Size_In_Bits; Expected_Size: Size_In_Bits) return Boolean; function Check(Subtype_Name: String; Subtype_Size: Size_In_Bits) return Boolean; type Longest_Signed_Integer is range Min_Int..Max_Int; end Size_Test_Utils; with Text_IO; use Text_IO; package body Size_Test_Utils is procedure Put_Line_Number is begin if Col /= 1 then raise Program_Error; end if; Put(Positive_Count'Image(Line)); Set_Col(8); end Put_Line_Number; procedure Put_Line(S: String) is begin Put_Line_Number; Text_Io.Put_Line(S); end Put_Line; procedure Heading(S: String) is begin New_Line; Set_Col(8); Text_Io.Put_Line(S); New_Line; end Heading; function Heading(S: String) return Boolean is begin Heading(S); return True; end Heading; function Img(X: Size_In_Bits) return String is begin return Size_In_Bits'Image(X); end Img; procedure Check(Subtype_Name: String; Subtype_Size: Size_In_Bits; Expected_Size: Size_In_Bits) is begin Put_Line_Number; Put(Subtype_Name & "'Size =" & Img(Subtype_Size)); if Subtype_Size = Expected_Size then Put(" (ok)"); else Put(" (expected" & Img(Expected_Size) & ")"); end if; Text_IO.Put_Line("."); end Check; procedure Check(Subtype_Name: String; Subtype_Size: Size_In_Bits) is begin Put_Line_Number; Put(Subtype_Name & "'Size =" & Img(Subtype_Size)); Text_IO.Put_Line("."); end Check; function Check(Subtype_Name: String; Subtype_Size: Size_In_Bits; Expected_Size: Size_In_Bits) return Boolean is begin Check(Subtype_Name, Subtype_Size, Expected_Size); return True; end Check; function Check(Subtype_Name: String; Subtype_Size: Size_In_Bits) return Boolean is begin Check(Subtype_Name, Subtype_Size); return True; end Check; end Size_Test_Utils; with Size_Test_Utils; use Size_Test_Utils; pragma Elaborate(Size_Test_Utils); package Size_Test_83_Pkg is -- This package prints out the 'Size of various subtypes. -- Ada-95-specific code is avoided here. -- The "..._Test" variables are ignored -- they're just there so we -- can call Check in a declaration context. package Signed_Integers is H1: Boolean := Heading("Signed Integers:"); type Positive_0 is range 0..0; Positive_0_Test: Boolean := Check("Positive_0", Positive_0'Size, 0); Positive_0_Base_Test: Boolean := Check("Positive_0'Base", Positive_0'Base'Size); type Positive_1 is range 0..1; Positive_1_Test: Boolean := Check("Positive_1", Positive_1'Size, 1); Positive_1_Base_Test: Boolean := Check("Positive_1'Base", Positive_1'Base'Size); type Positive_2 is range 0..2; Positive_2_Test: Boolean := Check("Positive_2", Positive_2'Size, 2); Positive_2_Base_Test: Boolean := Check("Positive_2'Base", Positive_2'Base'Size); type Integer_3 is range -2..2; Integer_3_Test: Boolean := Check("Integer_3", Integer_3'Size, 3); Integer_3_Base_Test: Boolean := Check("Integer_3'Base", Integer_3'Base'Size); type Billion is range -1_000_000_000 .. 1_000_000_000; subtype Sub_Pos_0 is Billion range 0..0; Sub_Pos_0_Test: Boolean := Check("Sub_Pos_0", Sub_Pos_0'Size, 0); subtype Sub_Pos_1 is Billion range 0..1; Sub_Pos_1_Test: Boolean := Check("Sub_Pos_1", Sub_Pos_1'Size, 1); subtype Sub_Pos_4 is Billion range 0..15; Sub_Pos_4_Test: Boolean := Check("Sub_Pos_4", Sub_Pos_4'Size, 4); subtype Sub_Int_7 is Billion range -127..127; Sub_Int_7_Test: Boolean := Check("Sub_Int_7", Sub_Int_7'Size, 7); end Signed_Integers; use Signed_Integers; package Enums is H1: Boolean := Heading("Enums:"); type Enum_0 is (Red); Enum_0_Test: Boolean := Check("Enum_0", Enum_0'Size, 0); Enum_0_Base_Test: Boolean := Check("Enum_0'Base", Enum_0'Base'Size, 0); type Enum_1 is (Red, Orange); Enum_1_Test: Boolean := Check("Enum_1", Enum_1'Size, 1); Enum_1_Base_Test: Boolean := Check("Enum_1'Base", Enum_1'Base'Size, 1); type Enum_2 is (Red, Orange, Yellow); Enum_2_Test: Boolean := Check("Enum_2", Enum_2'Size, 2); Enum_2_Base_Test: Boolean := Check("Enum_2'Base", Enum_2'Base'Size, 2); type Enum_4 is ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', Ten, Eleven, Twelve); Enum_4_Test: Boolean := Check("Enum_4", Enum_4'Size, 4); Enum_4_Base_Test: Boolean := Check("Enum_4'Base", Enum_4'Base'Size, 4); subtype Sub_Enum_0 is Enum_4 range '0'..'0'; Sub_Enum_0_Test: Boolean := Check("Sub_Enum_0", Sub_Enum_0'Size, 0); subtype Sub_Enum_1 is Enum_4 range '0'..'1'; Sub_Enum_1_Test: Boolean := Check("Sub_Enum_1", Sub_Enum_1'Size, 1); end Enums; use Enums; package Records is H1: Boolean := Heading("Records:"); type Unpacked_Rec is record A: Positive_2; B: Sub_Enum_1; end record; Unpacked_Rec_Test: Boolean := Check("Unpacked_Rec", Unpacked_Rec'Size); type Rec_3 is new Unpacked_Rec; pragma Pack(Rec_3); Rec_3_Test: Boolean := Check("Rec_3", Rec_3'Size, 3); Rec_3_Obj: Rec_3; A_Test: Boolean := Check("Rec_3_Obj.A", Rec_3_Obj.A'Size, 2); B_Test: Boolean := Check("Rec_3_Obj.B", Rec_3_Obj.B'Size, 2); type Rec_10 is record B1, B2, B3, B4, B5, B6, B7, B8, B9, B10: Boolean; end record; pragma Pack(Rec_10); Rec_10_Test: Boolean := Check("Rec_10", Rec_10'Size, 10); Rec_10_Obj: Rec_10; B1_Test: Boolean := Check("Rec_10_Obj.B1", Rec_10_Obj.B1'Size, 1); type Rec_32 is record X1, X2, X3: Rec_3; X4, X5: Integer_3; Two_Bits: Enum_2; Ten_Bits: Rec_10; end record; pragma Pack(Rec_32); Rec_32_Test: Boolean := Check("Rec_32", Rec_32'Size, 32); Rec_32_Obj: Rec_32; X2_Test: Boolean := Check("Rec_32_Obj.X2", Rec_32_Obj.X2'Size, 3); X5_Test: Boolean := Check("Rec_32_Obj.X5", Rec_32_Obj.X5'Size, 3); end Records; private procedure Require_Body; end Size_Test_83_Pkg; with System; use System; package body Size_Test_83_Pkg is package Predefined_Stuff is end; package body Predefined_Stuff is begin Heading("Predefined Stuff:"); Put_Line("Min_Int = " & Longest_Signed_Integer'Image(Min_Int)); Put_Line("Max_Int = " & Longest_Signed_Integer'Image(Max_Int)); Check("Longest_Signed_Integer", Longest_Signed_Integer'Size); Put_Line("Storage_Unit = " & Longest_Signed_Integer'Image(Storage_Unit)); Check("Address", Address'Size); Put_Line("Boolean'First = " & Boolean'Image(Boolean'First) & "."); Put_Line("Boolean'Last = " & Boolean'Image(Boolean'Last) & "."); Check("Boolean", Boolean'Size, 1); Put_Line("Integer'First = " & Integer'Image(Integer'First) & "."); Put_Line("Integer'Last = " & Integer'Image(Integer'Last) & "."); Check("Integer", Integer'Size); Put_Line("Natural'First = " & Natural'Image(Natural'First) & "."); Put_Line("Natural'Last = " & Natural'Image(Natural'Last) & "."); Check("Natural", Natural'Size); Put_Line("Positive'First = " & Positive'Image(Positive'First) & "."); Put_Line("Positive'Last = " & Positive'Image(Positive'Last) & "."); Check("Positive", Positive'Size); Put_Line("Character'First = " & Character'Image(Character'First) & "."); Put_Line("Character'Last = " & Character'Image(Character'Last) & "."); Check("Character", Character'Size, 8); end Predefined_Stuff; procedure Require_Body is begin null; end Require_Body; end Size_Test_83_Pkg; with Size_Test_Utils; use Size_Test_Utils; with Size_Test_83_Pkg; use Size_Test_83_Pkg; pragma Elaborate(Size_Test_Utils); pragma Elaborate(Size_Test_83_Pkg); package Size_Clause_83_Pkg is -- Same as Size_Test_83_Pkg, except this package concentrates on cases -- where the Size is specified in an attribute_definition_clause. -- Each subtype Foo_Spec corresponds to subtype Foo from -- Size_Test_83_Pkg. The declaration of Foo_Spec and Foo are -- the same, except that Foo_Spec has a Size clause. use Size_Test_83_Pkg.Signed_Integers; use Size_Test_83_Pkg.Enums; use Size_Test_83_Pkg.Records; package Signed_Integers is H1: Boolean := Heading("Signed Integers with Size Clauses:"); type Positive_0_Spec is range 0..0; for Positive_0_Spec'Size use 0; Positive_0_Spec_Test: Boolean := Check("Positive_0_Spec", Positive_0_Spec'Size, 0); Positive_0_Spec_Base_Test: Boolean := Check("Positive_0_Spec'Base", Positive_0_Spec'Base'Size); type Positive_1_Spec is range 0..1; for Positive_1_Spec'Size use 1; Positive_1_Spec_Test: Boolean := Check("Positive_1_Spec", Positive_1_Spec'Size, 1); Positive_1_Spec_Base_Test: Boolean := Check("Positive_1_Spec'Base", Positive_1_Spec'Base'Size); type Positive_2_Spec is range 0..2; for Positive_2_Spec'Size use 2; Positive_2_Spec_Test: Boolean := Check("Positive_2_Spec", Positive_2_Spec'Size, 2); Positive_2_Spec_Base_Test: Boolean := Check("Positive_2_Spec'Base", Positive_2_Spec'Base'Size); type Integer_3_Spec is range -2..2; for Integer_3_Spec'Size use 3; Integer_3_Spec_Test: Boolean := Check("Integer_3_Spec", Integer_3_Spec'Size, 3); Integer_3_Spec_Base_Test: Boolean := Check("Integer_3_Spec'Base", Integer_3_Spec'Base'Size); type Billion_Spec is range -1_000_000_000 .. 1_000_000_000; for Billion_Spec'Size use 31; Billion_Spec_Test: Boolean := Check("Billion_Spec", Billion_Spec'Size, 31); subtype Sub_Pos_0_Spec is Billion_Spec range 0..0; Sub_Pos_0_Spec_Test: Boolean := Check("Sub_Pos_0_Spec", Sub_Pos_0_Spec'Size, 0); subtype Sub_Pos_1_Spec is Billion_Spec range 0..1; Sub_Pos_1_Spec_Test: Boolean := Check("Sub_Pos_1_Spec", Sub_Pos_1_Spec'Size, 1); subtype Sub_Pos_4_Spec is Billion_Spec range 0..15; Sub_Pos_4_Spec_Test: Boolean := Check("Sub_Pos_4_Spec", Sub_Pos_4_Spec'Size, 4); subtype Sub_Int_7_Spec is Billion_Spec range -127..127; Sub_Int_7_Spec_Test: Boolean := Check("Sub_Int_7_Spec", Sub_Int_7_Spec'Size, 7); end Signed_Integers; use Signed_Integers; package Enums is H1: Boolean := Heading("Enums with Size Clauses:"); type Enum_0_Spec is (Red); for Enum_0_Spec'Size use 0; Enum_0_Spec_Test: Boolean := Check("Enum_0_Spec", Enum_0_Spec'Size, 0); Enum_0_Spec_Base_Test: Boolean := Check("Enum_0_Spec'Base", Enum_0_Spec'Base'Size, 0); type Enum_1_Spec is (Red, Orange); for Enum_1_Spec'Size use 1; Enum_1_Spec_Test: Boolean := Check("Enum_1_Spec", Enum_1_Spec'Size, 1); Enum_1_Spec_Base_Test: Boolean := Check("Enum_1_Spec'Base", Enum_1_Spec'Base'Size, 1); type Enum_2_Spec is (Red, Orange, Yellow); for Enum_2_Spec'Size use 2; Enum_2_Spec_Test: Boolean := Check("Enum_2_Spec", Enum_2_Spec'Size, 2); Enum_2_Spec_Base_Test: Boolean := Check("Enum_2_Spec'Base", Enum_2_Spec'Base'Size, 2); type Enum_4_Spec is ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', Ten, Eleven, Twelve); for Enum_4_Spec'Size use 4; Enum_4_Spec_Test: Boolean := Check("Enum_4_Spec", Enum_4_Spec'Size, 4); Enum_4_Spec_Base_Test: Boolean := Check("Enum_4_Spec'Base", Enum_4_Spec'Base'Size, 4); subtype Sub_Enum_0_Spec is Enum_4_Spec range '0'..'0'; Sub_Enum_0_Spec_Test: Boolean := Check("Sub_Enum_0_Spec", Sub_Enum_0_Spec'Size, 0); subtype Sub_Enum_1_Spec is Enum_4_Spec range '0'..'1'; Sub_Enum_1_Spec_Test: Boolean := Check("Sub_Enum_1_Spec", Sub_Enum_1_Spec'Size, 1); type Six_Bit_Enum_4_Spec is ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', Ten, Eleven, Twelve); for Six_Bit_Enum_4_Spec'Size use 6; -- Non-default Size Six_Bit_Enum_4_Spec_Test: Boolean := Check("Six_Bit_Enum_4_Spec", Six_Bit_Enum_4_Spec'Size, 6); Six_Bit_Enum_4_Spec_Base_Test: Boolean := Check("Six_Bit_Enum_4_Spec'Base", Six_Bit_Enum_4_Spec'Base'Size, 6); subtype Sub_Six_Bit_Enum_0_Spec is Six_Bit_Enum_4_Spec range '0'..'0'; Sub_Six_Bit_Enum_0_Spec_Test: Boolean := Check("Sub_Six_Bit_Enum_0_Spec", Sub_Six_Bit_Enum_0_Spec'Size, 0); subtype Sub_Six_Bit_Enum_1_Spec is Six_Bit_Enum_4_Spec range '0'..'1'; Sub_Six_Bit_Enum_1_Spec_Test: Boolean := Check("Sub_Six_Bit_Enum_1_Spec", Sub_Six_Bit_Enum_1_Spec'Size, 1); subtype Sub_Six_Bit_Enum_6_Spec is Six_Bit_Enum_4_Spec range '0'..Twelve; Sub_Six_Bit_Enum_6_Spec_Test: Boolean := Check("Sub_Six_Bit_Enum_6_Spec", Sub_Six_Bit_Enum_6_Spec'Size, 6); end Enums; use Enums; package Records is H1: Boolean := Heading("Records with Size Clauses:"); type Unpacked_Rec_Spec is record A: Positive_2_Spec; B: Sub_Enum_1_Spec; end record; Unpacked_Rec_Spec_Test: Boolean := Check("Unpacked_Rec_Spec", Unpacked_Rec'Size); type Rec_3_Spec is new Unpacked_Rec_Spec; pragma Pack(Rec_3_Spec); for Rec_3_Spec'Size use 3; Rec_3_Spec_Test: Boolean := Check("Rec_3_Spec", Rec_3_Spec'Size, 3); Rec_3_Spec_Obj: Rec_3_Spec; A_Test: Boolean := Check("Rec_3_Spec_Obj.A", Rec_3_Spec_Obj.A'Size, 2); B_Test: Boolean := Check("Rec_3_Spec_Obj.B", Rec_3_Spec_Obj.B'Size, 2); type Rec_10_Spec is record B1, B2, B3, B4, B5, B6, B7, B8, B9, B10: Boolean; end record; pragma Pack(Rec_10_Spec); for Rec_10_Spec'Size use 10; Rec_10_Spec_Test: Boolean := Check("Rec_10_Spec", Rec_10_Spec'Size, 10); Rec_10_Spec_Obj: Rec_10_Spec; B1_Test: Boolean := Check("Rec_10_Spec_Obj.B1", Rec_10_Spec_Obj.B1'Size, 1); type Rec_32_Spec is record X1, X2, X3: Rec_3_Spec; X4, X5: Integer_3_Spec; Two_Bits: Enum_2_Spec; Ten_Bits: Rec_10_Spec; end record; pragma Pack(Rec_32_Spec); for Rec_32_Spec'Size use 32; Rec_32_Spec_Test: Boolean := Check("Rec_32_Spec", Rec_32_Spec'Size, 32); Rec_32_Spec_Obj: Rec_32_Spec; X2_Test: Boolean := Check("Rec_32_Spec_Obj.X2", Rec_32_Spec_Obj.X2'Size, 3); X5_Test: Boolean := Check("Rec_32_Spec_Obj.X5", Rec_32_Spec_Obj.X5'Size, 3); end Records; end Size_Clause_83_Pkg; with Size_Test_Utils; use Size_Test_Utils; with Size_Test_83_Pkg; use Size_Test_83_Pkg; with Size_Clause_83_Pkg; use Size_Clause_83_Pkg; pragma Elaborate(Size_Test_Utils); pragma Elaborate(Size_Test_83_Pkg); pragma Elaborate(Size_Clause_83_Pkg); package Size_Test_95_Pkg is -- Same purpose as Size_Test_83_Pkg and Size_Clause_83_Pkg, -- but we put all the Ada-95-only declarations here. package Signed_Integers is H1: Boolean := Heading("Ada 95 Signed Integers:"); use Size_Test_83_Pkg.Signed_Integers; use Size_Clause_83_Pkg.Signed_Integers; subtype Positive_0_B is Positive_0'Base range -Positive_0'Last..Positive_0'Last; Positive_0_B_Test: Boolean := Check("Positive_0_B", Positive_0_B'Size, 0); subtype Positive_0_BB is Positive_0'Base range 0..Positive_0'Last; Positive_0_BB_Test: Boolean := Check("Positive_0_BB", Positive_0_BB'Size, 0); subtype Positive_0_Spec_B is Positive_0_Spec'Base range -Positive_0_Spec'Last..Positive_0_Spec'Last; Positive_0_Spec_B_Test: Boolean := Check("Positive_0_Spec_B", Positive_0_Spec_B'Size, 0); subtype Positive_0_Spec_BB is Positive_0_Spec'Base range 0..Positive_0_Spec'Last; Positive_0_Spec_BB_Test: Boolean := Check("Positive_0_Spec_BB", Positive_0_Spec_BB'Size, 0); subtype Positive_1_B is Positive_1'Base range -Positive_1'Last..Positive_1'Last; Positive_1_B_Test: Boolean := Check("Positive_1_B", Positive_1_B'Size, 2); subtype Positive_1_BB is Positive_1'Base range 0..Positive_1'Last; Positive_1_BB_Test: Boolean := Check("Positive_1_BB", Positive_1_BB'Size, 2); subtype Positive_1_Spec_B is Positive_1_Spec'Base range -Positive_1_Spec'Last..Positive_1_Spec'Last; Positive_1_Spec_B_Test: Boolean := Check("Positive_1_Spec_B", Positive_1_Spec_B'Size, 2); subtype Positive_1_Spec_BB is Positive_1_Spec'Base range 0..Positive_1_Spec'Last; Positive_1_Spec_BB_Test: Boolean := Check("Positive_1_Spec_BB", Positive_1_Spec_BB'Size, 2); subtype Positive_2_B is Positive_2'Base range -Positive_2'Last..Positive_2'Last; Positive_2_B_Test: Boolean := Check("Positive_2_B", Positive_2_B'Size, 3); subtype Positive_2_BB is Positive_2'Base range 0..Positive_2'Last; Positive_2_BB_Test: Boolean := Check("Positive_2_BB", Positive_2_BB'Size, 3); subtype Positive_2_Spec_B is Positive_2_Spec'Base range -Positive_2_Spec'Last..Positive_2_Spec'Last; Positive_2_Spec_B_Test: Boolean := Check("Positive_2_Spec_B", Positive_2_Spec_B'Size, 3); subtype Positive_2_Spec_BB is Positive_2_Spec'Base range 0..Positive_2_Spec'Last; Positive_2_Spec_BB_Test: Boolean := Check("Positive_2_Spec_BB", Positive_2_Spec_BB'Size, 3); subtype Integer_3_B is Integer_3'Base range -Integer_3'Last..Integer_3'Last; Integer_3_B_Test: Boolean := Check("Integer_3_B", Integer_3_B'Size, 3); subtype Integer_3_BB is Integer_3'Base range 0..Integer_3'Last; Integer_3_BB_Test: Boolean := Check("Integer_3_BB", Integer_3_BB'Size, 2); subtype Integer_3_Spec_B is Integer_3'Base range -Integer_3'Last..Integer_3'Last; Integer_3_Spec_B_Test: Boolean := Check("Integer_3_Spec_B", Integer_3_Spec_B'Size, 3); subtype Integer_3_Spec_BB is Integer_3'Base range 0..Integer_3'Last; Integer_3_Spec_BB_Test: Boolean := Check("Integer_3_Spec_BB", Integer_3_Spec_BB'Size, 2); end Signed_Integers; package Modular_Integers is H1: Boolean := Heading("Ada 95 Modular Integers:"); type Mod_0 is mod 2**0; Mod_0_Test: Boolean := Check("Mod_0", Mod_0'Size, 0); Mod_0_Base_Test: Boolean := Check("Mod_0'Base", Mod_0'Base'Size); type Mod_1 is mod 2**1; Mod_1_Test: Boolean := Check("Mod_1", Mod_1'Size, 1); Mod_1_Base_Test: Boolean := Check("Mod_1'Base", Mod_1'Base'Size); type Mod_2 is mod 2**2; Mod_2_Test: Boolean := Check("Mod_2", Mod_2'Size, 2); Mod_2_Base_Test: Boolean := Check("Mod_2'Base", Mod_2'Base'Size); type Mod_32 is mod 2**32; Mod_32_Test: Boolean := Check("Mod_32", Mod_32'Size, 32); Mod_32_Base_Test: Boolean := Check("Mod_32'Base", Mod_32'Base'Size); type Million is mod 1_000_000; subtype Sub_Mod_0 is Million range 0..0; Sub_Mod_0_Test: Boolean := Check("Sub_Mod_0", Sub_Mod_0'Size, 0); subtype Sub_Mod_1 is Million range 0..1; Sub_Mod_1_Test: Boolean := Check("Sub_Mod_1", Sub_Mod_1'Size, 1); subtype Sub_Mod_4 is Million range 0..15; Sub_Mod_4_Test: Boolean := Check("Sub_Mod_4", Sub_Mod_4'Size, 4); subtype Sub_Int_7 is Million range 0..100; Sub_Int_7_Test: Boolean := Check("Sub_Int_7", Sub_Int_7'Size, 7); end Modular_Integers; private procedure Require_Body; end Size_Test_95_Pkg; with System; use System; with System.Storage_Elements; use System.Storage_Elements; package body Size_Test_95_Pkg is package Predefined_Stuff is end; package body Predefined_Stuff is H1: Boolean := Heading("Ada 95 Predefined Stuff:"); type Longest_Binary_Modular is mod Max_Binary_Modulus; type Longest_Nonbinary_Modular is mod Max_Nonbinary_Modulus; Max_Binary_Modulus_Minus_One: constant := Max_Binary_Modulus - 1; Max_Nonbinary_Modulus_Minus_One: constant := Max_Nonbinary_Modulus - 1; begin Put_Line("Max_Binary_Modulus = " & Longest_Binary_Modular'Image(Max_Binary_Modulus_Minus_One) & " + 1"); Check("Longest_Binary_Modular", Longest_Binary_Modular'Size); Put_Line("Max_Nonbinary_Modulus = " & Longest_Nonbinary_Modular'Image(Max_Nonbinary_Modulus_Minus_One) & " + 1"); Check("Longest_Nonbinary_Modular", Longest_Nonbinary_Modular'Size); Put_Line("Word_Size = " & Longest_Signed_Integer'Image(Word_Size)); Check("Storage_Element", Storage_Element'Size, Storage_Unit); Put_Line("Wide_Character'First = " & Wide_Character'Image(Wide_Character'First) & "."); Put_Line("Wide_Character'Last = " & Wide_Character'Image(Wide_Character'Last) & "."); Check("Wide_Character", Wide_Character'Size, 16); end Predefined_Stuff; procedure Require_Body is begin null; end Require_Body; end Size_Test_95_Pkg; -- This is a main program that calls the Ada 83 parts of the Size test. -- See also Size_Test_95. -- All the work is done during elaboration of the Size_..._Pkg packages. with Text_IO; use Text_IO; with Size_Test_83_Pkg; with Size_Clause_83_Pkg; procedure Size_Test_83 is begin New_Line; Put_Line("[Size_Test_83 done.]"); end Size_Test_83; -- This is a main program that calls the Ada 83 *and* Ada 95 parts -- of the Size test. -- See also Size_Test_83. -- All the work is done during elaboration of the Size_..._Pkg packages. with Text_IO; use Text_IO; with Size_Test_83_Pkg; with Size_Clause_83_Pkg; with Size_Test_95_Pkg; procedure Size_Test_95 is begin New_Line; Put_Line("[Size_Test_95 done.]"); end Size_Test_95; From phl@rational.com Wed Apr 17 10:40:03 1996 Return-Path: Received: from inmet.camb.inmet.com by dsd.camb.inmet.com (4.1/SMI-4.1) id AA06768; Wed, 17 Apr 96 10:40:03 EDT Received: from sw-eng.falls-church.va.us (ns1.sw-eng.falls-church.va.us) by inmet.camb.inmet.com (4.1/SMI-4.1) id AA12291; Wed, 17 Apr 96 10:40:14 EDT Received: from rational2.rational.com by sw-eng.falls-church.va.us (8.7.1/) id OAA29191; Wed, 17 Apr 1996 14:39:20 GMT Received: from igor (igor.rational.com [89.64.2.102]) by rational2.rational.com (8.6.12/8.6.9) with ESMTP id HAA16598; Wed, 17 Apr 1996 07:39:54 -0700 Received: from sorbonne.rational.com (sorbonne.rational.com [89.30.2.172]) by igor (8.6.9/igor-1.0-wwong) with ESMTP id HAA14798; Wed, 17 Apr 1996 07:39:51 -0700 Received: from eiffel.Rational.COM (eiffel [89.30.1.2]) by sorbonne.rational.com (8.6.9/8.6.9) with SMTP id QAA27917; Wed, 17 Apr 1996 16:38:17 +0200 From: "Pascal Leroy" Message-Id: <9604171638.ZM2411@rational.com> Date: Wed, 17 Apr 1996 16:38:16 +0200 In-Reply-To: bobduff@world.std.com (Robert A Duff) "Re: Dewar's comments on the SIZE problem and Issue" (Apr 17, 6:03) References: <199604162033.AA28752@world.std.com> Organization: Rational Software Corporation Phone: +33 (1) 30 12 09 50 Reply-To: pleroy@Rational.COM X-Mailer: Z-Mail (3.2.0 06sep94) To: ada-comment@sw-eng.falls-church.va.us Subject: Re: Dewar's comments on the SIZE problem and Issue Cc: bobduff@world.std.com (Robert A Duff), dewar@gnat.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii !topic Re: Dewar's comments on the SIZE problem and Issue !reference RM95-13.1(14) !reference RM95-13.3(55) !reference 96-5486.a Robert Dewar !reference 96-5487.a Robert A Duff 96-4-13 !reference 96-5495.a Robert A Duff 96-4-16 !from Bob Duff 96-4-17 <> !discussion I suppose we'll have an interesting discussion at the next ARG meeting, assuming RBKD is there. I, for one, strongly disagree with the suggestions below, and agree with (the current wording of) AI95-00109 > Anyway, Robert recommends the following (I'm paraphrasing what he wrote): > > Keep the RM rules (13.3(55)) as they are with respect to default > sizes. Add a rule that the minimum size default rule does not apply > to subtypes that happen to statically match the first subtype. > > Implementation Permission: *Allow* implementations to support Size > clauses for secondary subtypes. I don't see what is gained by this. Certainly not portability, since we don't _require_ support for such clauses. The only reason for this permission is that it makes it more likely that, if vendors want to support this capability, they'll use the same mechanism. But then we have to assume that vendors are not completely stupid: if GNAT for instance supports a 'Subtype_Size attribute, and there appears to be good reasons for other vendors to support the same capability then it would be sensible for them to use the attribute 'Subtype_Size. There are many uniformity issues like that, and we don't have to incorporate them in the language: we can just assume that reasonable choices will be made. I suspect that if we put this permission in the language, we'll spend the next five years explaining how all the rest of the RM works in the presence of a size clause for subtypes. > Say that two subtypes do not statically match if their Sizes differ > (this can be interesting only if one or other of them is a subtype whose > Size has been set using the above permission). Now that violates the separation principle (grab your Ada 83 Rationale and read section 15.1 to refresh your memory) and I think it's BAD, and that the language is insufficiently broken here to abandon the separation between the logical properties and the representation. > Robert notes that if the above Implementation Permission is not granted > by the ARG, then GNAT will implement essentially the same thing, but > call it by a different name ('Subtype_Size). This is important, because > when porting real Ada 83 code to GNAT, such a feature has been needed. I would be curious to see an example of such real Ada 83 code that absolutely requires 'Size clauses for subtype. So far, no convincing example has been shown: Robert's Number_Of_Hotels and Number_Of_Companies stuff looked more like an example of how to misuse subtypes. _____________________________________________________________________ Pascal Leroy +33.1.30.12.09.68 pleroy@rational.com +33.1.30.12.09.66 FAX