ATL*_*DEV 5 optimization constants ada
假设我声明了一个常量值数组用作查找表:
function Square(num : Integer) return Integer is
use Ada.Text_IO;
type LookupItemsRange is range 1..10;
type LookupTable is array(LookupItemsRange) of integer;
A : constant LookupTable := (2312,2,3,4,5,6,7,8,9, 10);
begin
    Sqr := A(1);
    Sqr := 2 * A(2);
    return Sqr;
end Square;
Run Code Online (Sandbox Code Playgroud)
LookupTable 不应使用任何空间。编译器应该能够用实际的内联值替换数组访问。在最高优化设置下,Ada 的结果如下:
_ada_square:
        li      a0,4                #,
        ret     
Run Code Online (Sandbox Code Playgroud)
我计划用更清晰的查找表实现替换大量冗余的 MCU 代码。由于微控制器的资源有限,我想避免不必要的分配和索引。
什么情况下Ada会分配数组或者我完全安全?
因此,对于 Ada 语言规范,您将无法获得数组对象的保证。在即将发布的最新版本 (Ada2022) 中,Ada 开始赶上 constexpr,但只会向表达式函数提供其类似的属性( Ada 中的Static)(将它们视为与 constexpr 函数类似,但限制略有不同)。
因此,如果您不介意依赖编译器供应商,那么该数组很可能会正常工作(但不能保证)。如果您想要更多语言支持的优化保证,那么您将需要使用具有静态方面集的表达式函数来模拟数组(在最近的编译器中)。对于静态输入,静态表达式函数将给出静态结果(同样是 Ada 中的静态,而不是 C++ 中的静态,更像 constexpr)。
function Square return Integer is
    type Lookup_Items_Range is range 1..10;
    function A(Index : Lookup_Items_Range) return Integer is 
        (case Index is
            when 1 => 2312,
            when 2 => 2,
            when 3 => 3,
            when 4 => 4,
            when 5 => 5,
            when 6 => 6,
            when 7 => 7,
            when 8 => 8,
            when 9 => 9,
            when 10 => 10
         ) 
    with Static;
    Sqr : Integer;
begin
    Sqr := A(1);
    Sqr := 2 * A(2);
    return Sqr;
    
end Square;
Run Code Online (Sandbox Code Playgroud)
它比使用数组稍微冗长一些,但有语言支持,这在某些嵌入式编程领域非常重要。请注意,大多数最新的编译器都需要一个开关来启用此功能,因为它太新了,但它们通常会在错误消息中告诉您该开关。我使用 GNAT 12.1 在 godbolt 上进行了测试,并使用正确的开关进行了编译。