我有一个需要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位的倍数。
答案 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.
。