Ada"常量"关键字内存使用情况

bac*_*ash 1 ada

请考虑以下代码:

My_Constant : constant := 2;
Run Code Online (Sandbox Code Playgroud)

"My_Constant"是变量还是C语言宏,它在内存中是否有存储?

ajb*_*ajb 7

请注意,这constant只是意味着您无法修改对象.它并不一定意味着在编译时已知常量的值.因此有三种情况需要考虑:

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

My_Constant : constant Integer := 3;
Run Code Online (Sandbox Code Playgroud)

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

在更复杂的情况下:

My_Record_Constant : constant Rec := (Field_1 => 100, Field_2 => 201, Field_3 => 44);
Run Code Online (Sandbox Code Playgroud)

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

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

My_Constant : aliased constant Integer := 3;
Run Code Online (Sandbox Code Playgroud)

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

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

My_Constant : constant Integer := Some_Function_Call (Parameter_1);
Run Code Online (Sandbox Code Playgroud)

当详细说明整数的声明时,该函数被调用一次.由于它不是宏扩展,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;
Run Code Online (Sandbox Code Playgroud)

Some_Function_Call每次被调用时Some_Procedure调用,但它被调用一次,而不是两次或三次.

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

(3)命名号码.这是你有的例子,没有类型:

My_Constant : constant := 2;
Run Code Online (Sandbox Code Playgroud)

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