阿达类型的大小差异

时间:2014-02-02 02:02:26

标签: size ada

我有这个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.这两个声明之间有什么区别?

2 个答案:

答案 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位整数类型。