我有这个Ada计划:
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;
procedure test is
type MY_TYPE is new Integer range 1..20;
subtype MY_TYPE2 is MY_TYPE range 5..6;
c : MY_TYPE:=10;
f : MY_TYPE2 :=6;
begin
put(Integer(c'SIZE));
end test;
当我运行它时,我得到32.如果我替换
type MY_TYPE is new Integer range 1..20;
与
type MY_TYPE is range 1..20;
我得到8.这两个声明之间有什么区别?
答案 0 :(得分:4)
您允许编译器选择这些不同类型声明的大小,并根据其基本类型(INTEGER)的大小选择INTEGER类型的大小。
您可以控制这些类型的大小:如果您将第一个声明重写为
type MY_TYPE is new Integer range 1..20;
for MYTYPE'SIZE use 8;
你应该得到一个8位的MY_TYPE。
for MYTYPE'SIZE use 5;
应该将MYTYPE打包成5位(据我所知,允许编译器通过显式错误拒绝它,或生成正确的代码,但不接受它并生成垃圾。)
为什么要将MYTYPE
打包成5位?一个原因是它是否被用作记录的一个组成部分:只要它们是布尔值并且它们的SIZE
属性为1,就可以在一个字节中留出3个以上的组件空间!
这可能看起来像极端打包,但它实际上在嵌入式编程中很常见,其中该记录类型与外设或I / O端口中的位匹配。您还可以在记录中指定位级布局,如:
type Prescale is new Integer range 1..20;
for Prescale'SIZE use 5;
type Timer_Ctrl_Reg is record
Scale : Prescale;
Up : Boolean;
Repeat : Boolean;
Int_En : Boolean;
end record;
for Timer_Ctrl_Reg use record
Scale at 0 range 0 .. 4;
Up at 0 range 5 .. 5;
Repeat at 0 range 6 .. 6;
Int_En at 0 range 7 .. 7;
end record;
at
指定“存储单元”中记录基数的偏移量,通常是字节或单词:range
指定存储单元中的位位置。
不再担心狡猾的位掩盖和提取!
另一方面,
for MYTYPE'SIZE use 4;
应该失败,因为MYTYPE有超过16个离散值。
答案 1 :(得分:3)
此:
type MY_TYPE is new Integer range 1..20;
明确地从MY_TYPE
继承Integer
,这显然是您系统上的32位。
此:
type MY_TYPE is range 1..20;
让编译器决定从继承MY_TYPE
的内容如何表示MY_TYPE
。结果是特定于实现的;显然你的编译器选择将它实现为8位整数类型。