繁体   English   中英

Ada“常量”关键字的内存使用情况

[英]Ada “constant” keyword memory usage

考虑以下代码:

My_Constant : constant := 2;

“ My_Constant”是变量还是类似于C语言的宏,因此它在内存中是否有存储?

请注意, constant仅表示您无法修改对象。 不一定意味着在编译时就知道常数的值。 因此,需要考虑三种情况:

(1)具有类型的常量,其值在编译时已知:

My_Constant : constant Integer := 3;

在这种情况下,编译器没有理由为常量分配内存。 它在每次看到My_Constant时都可以使用值3(并且在可能的情况下可能使用3作为指令的立即操作数;如果它看到类似My_Constant * 2则可以使用值6作为立即操作数)。 允许编译器为常量分配内存,但我认为在像这样的简单情况下,数量很少,任何体面的编译器都不会这样做。 如果它是一个很大的数字,不适合立即数操作数,那么在某个地方为该数字分配空间可能更有意义(如果这样做可以节省代码空间)。

在更复杂的情况下:

My_Record_Constant : constant Rec := (Field_1 => 100, Field_2 => 201, Field_3 => 44);

在这里,一个好的编译器可以根据常量的使用方式来决定是否将常量存储在内存中。 如果唯一的用途是访问单个字段( My_Record_Constant.Field_1 ),则编译器可以将它们替换为整数值,就好像它们是整数常量一样,并且不需要将整个记录存储在内存中。

但是,使用aliased将导致任何常量被强制进入内存:

My_Constant : aliased constant Integer := 3;

现在必须分配内存,因为程序可以说My_Constant'Access (访问类型必须是access constant Integer )。

(2)在编译时未知其值的常数:

My_Constant : constant Integer := Some_Function_Call (Parameter_1);

详细说明整数的声明 ,该函数将被调用一次 由于它不是宏扩展,因此使用My_Constant不会生成对该函数的调用。 例:

procedure Some_Procedure is
    My_Constant : constant Integer := Some_Function_Call (Parameter_1);
begin
    Put_Line (Integer'Image (My_Constant));
    Put_Line (Integer'Image (My_Constant));
end Some_Procedure;

Some_Function_Call调用Some_Function_Call都会调用Some_Procedure ,但调用一次 ,而不是两次或三次。

最有可能的是,这需要将值存储在内存中以保存函数结果,因此将为My_Constant分配空间。 (这仍然不是Some_Function_Call 。如果一个好的优化编译器可以某种方式找出Some_Function_Call将返回一个已知值,则它可以使用该信息。)

(3)命名号码。 这是您的示例,其中没有类型:

My_Constant : constant := 2;

语言规则说,必须在编译时知道该值。 这等效于每次看到My_Constant都使用该数字,因此它是您要在Ada中获得的C宏最接近的东西。 但是效果基本上与(1)中相同[除了对类型兼容性的限制较少之外]。 编译器可能不会为其分配空间,但可能会为更大的值分配空间。 请注意,此语法仅适用于数值(整数或实数)。

上面选项(1)的另一个变体是常量数组。

primes : constant array(integer range <>) of integer := (1, 3, 5, 7, 11, 13, 17, 19, 23);

如果编译器可以看到它正在被索引访问,则它必须存储该数组。 我怀疑编译器作者是否会尝试在特殊情况下使用任何其他晦涩的转折条件来节省一些内存-他们在Ada中是否有足够的其他特殊情况需要担心!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM