强制Ada使用gnat 4.4对枚举类型使用最小规格大小

时间:2013-05-08 18:03:39

标签: size ada gnat

我有一个需要4位的枚举类型但是当我声明该类型的变量时,编译器会将该变量赋值为8位。

以下是代码的简化版本。

subtype ab_range_index is word range 0..3;
type ab_buffer_type is array(ab_range_index) of bit;

type Buffer is record
   ...
   var1        : some_buffer_type;
   Orig_AB_var : ab_buffer_type; 
   ...
end record;
for Buffer use record
  ...
  var1         at 16 range 0..5;
  Orig_AB_var  at 16 range 6..9;
  ...
end record;
...
type AB_type is (A,B);
for AB_type use (A => 0, B => 5);
for AB_type'Size use 4;
...
procedure Proc(AB_buff : ab_buffer_type) is 
AB_var : AB_type;                      -- AB_var'Size returns 8 in debugger.
for AB_var use at AB_buff'Address;
begin
   data_valid = AB_var'valid;          -- returns false since the variable 
                                       -- contains extra bits
   ...     

这一切都在以前的gnat版本下工作,但不是在gnat 4.4.6下。我知道gnat符合Ada规范。

有没有办法强制编译器将上例中的AB_var设为4位? 我试过'Object_Size但它需要是8位的倍数。

3 个答案:

答案 0 :(得分:1)

我不知道任何可以为变量分配4位的现代计算机硬件。最小值为8位字节。

没有冒犯,但我怀疑任何以前版本的GNAT都能够做到这一点。

现在在具有关联的rep规范或合适的约定pragma的记录中,AB_Type类型的单个字段只能分配4位。

但不是作为离散变量。

答案 1 :(得分:1)

Pragma Pack( [type_name] );添加到类型中,尤其是添加到记录中。我最近有一个案例,除非pack附加到该类型,否则即使是记录规范条款也不会起作用。 (也可以使用方面形式。)

答案 2 :(得分:1)

发布可编辑的复制器几乎总有一些东西可以说。我不确定你的代码是什么样的,但是对于GCC 4.8.0来说这很好用:

with Ada.Text_IO; use Ada.Text_IO;
procedure Small_Parameter_Conversion is
   type M_N_Type is (M, N);
   for M_N_Type use (M => 0, N => 5);
   for M_N_Type'Size use 4;
   type Fill is array (Positive range <>) of Boolean;
   for Fill'Component_Size use 1;
   type Import is record
      M_N : M_N_Type;
      Filler : Fill (1 .. 4);
   end record;
   for Import use record
      M_N at 0 range 0 .. 3;
      Filler at 0 range 4 .. 7;
   end record;
   type A_B_Type is (A, B);
   for A_B_Type use (A => 0, B => 5);
   for A_B_Type'Size use 4;
   procedure Proc (Input : M_N_Type) is
      A_B : A_B_Type;
      for A_B'Address use Input'Address;
   begin
      if not A_B'Valid then
         Put_Line ("invalid.");
      else
         Put_Line (A_B'Img);
      end if;
   end Proc;
   V : Import;
begin
   V := (M_N => M, Filler => (others => True));
   Proc (V.M_N);
   V := (M_N => N, Filler => (others => True));
   Proc (V.M_N);
end Small_Parameter_Conversion;

那就是说,Unchecked_Conversion是更好的方式。最后一段,但GNAT Reference Manual section on Address Clauses中有两个指出使用叠加是依赖于实现的(尽管我无法找到它在RM中的位置)。

错误的一种可能途径是M_N_Type实际上定义为

type M_N_Type is (M, N, O);
for M_N_Type use (M => 0, N => 5, O => 6);

Proc被称为

V := (M_N => O, Filler => (others => True));
Proc (V.M_N);

然后,当然,它会打印invalid.