在不知道其确切内容的情况下初始化记录

Nol*_*ola 1 ada

我的项目中有一个来自外部团队的源文件,我无法修改它。它包含定义寄存器内容的记录:

type R_Field is (R_FALSE, R_TRUE) with Size => 1;
for R_Field use (R_FALSE => 16#0#, R_TRUE => 16#1#);
type W_Field is (W_FALSE, W_TRUE) with Size => 1;
for W_Field use (W_FALSE => 16#0#, W_TRUE => 16#1#);
type U_Field is (U_FALSE, U_TRUE) with Size => 1;
for U_Field use (U_FALSE => 16#0#, U_TRUE => 16#1#);
type My_Register is record
        R : R_Field;
        W : W_Field;
        U : U_Field;
end record with Size => 32, Object_Size => 32;

for My_Register use record
        R at 0 range 0 .. 0;
        W at 0 range 1 .. 1;
        U at 0 range 5 .. 5;
end record;
Run Code Online (Sandbox Code Playgroud)

我正在编写一个驱动程序,它将针对许多不同的目标构建,每个目标都有自己的寄存器文件。对于寄存器文件的某些变体,My_Register 记录将没有 U 字段。

我正在尝试以将所有字段设置为 0 的方式在代码中初始化 My_Register 记录。我希望我的代码在定义 U 的情况和未定义 U 的情况下都能工作。

我不能这样做reg : My_Register := (R => R_FALSE, W => W_FALSE, U => U_FALSE),因为在寄存器文件中未定义 U 和 U_FALSE 的情况下,这不会编译。

有没有一种方法可以对整个记录进行零初始化,就像= {0}在 C 中那样?

Nik*_*sti 5

因此,您有一些针对不同目标而不同的代码(记录类型定义)。因此,您的构建系统有某种方法来选择用于所选目标的源文件。我建议您使记录初始化源代码对于不同的目标也有所不同,使构建系统以与为该目标选择包含记录类型声明的正确源文件相同的方式为每个目标选择正确的源文件。这同样适用于任何必须访问 U 组件(如果存在)的代码。

如果 (others => <>) 保证零初始化,您的问题的答案是“否”。它要求所有组件的默认初始化,因此要获得“零”初始化,每个组件的类型应具有默认值“零”(或“R_FALSE”等),这需要添加默认值方面来自外部团队的类型声明,似乎您不允许这样做。

如果您不想使用特定于目标的源文件方法,但您确定所有目标的记录大小都是 32 位,则可以实例化一个 Unchecked_Conversion 函数,从“mod 2**32”到记录类型,并将该转换应用于零值以获得具有 32 个零位的记录值。当然,Unchecked_Conversion 是一种可能会导致以后出现问题的黑客行为。