簡體   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