potentially simple and obvious question, but… Is type conversion not a static compilable expression?
I am testing the following code in Compiler Explorer:
pragma Source_File_Name (Square, Body_File_Name => "example.adb");
pragma Ada_2022;
-- Type your code here, or load an example.
function Square(num : Integer) return Float is
type My_Smol_Float is digits 5;
Floaty : constant := My_Smol_Float(num);
begin
return Float(Floaty**2);
end Square;
And I am getting the following error from the compiler:
gcc -c -I/app/ -g -fdiagnostics-color=always -S -fverbose-asm -masm=intel -O3 -march=znver4 -o /app/example.s -I- <source>
gnatmake: "<source>" compilation error
example.adb:10:26: error: non-static expression used in number declaration
example.adb:10:40: error: "num" is not static constant or named number (RM 4.9(5))
Compiler returned: 4
So… Type conversion cannot be done in the declarative part of functions/procedures? I would have expected it to be a Static/compile-time expression…
How could this be a compile-time expression when the parameter is a run-time value?
Try:
function Square (num : Integer) return Float is
type My_Smol_Float is digits 5;
Floaty : constant My_Smol_Float := My_Smol_Float (num);
begin
return Float (Floaty**2);
end Square;
pragma Source_File_Name (Square, Body_File_Name => "example.adb");
pragma Ada_2022;
-- Type your code here, or load an example.
function Square(num : Integer) return Float is
type My_Smol_Float is digits 7;
Floaty : constant array (1..5) of My_Smol_Float := (others => My_Smol_Float(num));
Accumulator : My_Smol_Float;
begin
for N of Floaty loop
Accumulator := @ + N;
end loop;
return Float(Accumulator);
end Square;
And Static expressions can use parameters that may not be fully known (but need to be developed at a later stage):
function If_Then_Else (Flag : Boolean; X, Y : Integer) return Integer is
(if Flag then X else Y) with Static;
Static, as applied to expressions, essentially means an expression that can be evaluated by the compiler (although it’s more constrained than that). Clearly, that doesn’t apply here.
As applied to expression functions, the definition is a bit different. It essentially means an expression function that always returns the same value for the same inputs.
Though that does still not explain why this line works in the declarative part… Is there some kind of elaboration that is allowed here or something? Maybe Ada pushes this as part of the declarative section into the execution section silently?
This last comment seems a bit confused to me. You seem to be partially merging the meanings of four different but admittedly related things – “named numbers”, “constant objects”, “static expressions”, and “static functions”. In particular, a static function is one that can be used in a static expression if all of the inputs are themselves static expressions. But if you apply a static function to a non-static expression, you end up with a non-static expression.
Named numbers (X : constant := ) require that their initialization expression be a static expression of a numeric type. Constant objects have no particular restrictions, but a constant object can be used in a static expression if its initialization expression is a static expression of a numeric or string type (and its subtype is static).
But to answer the question posed in the subject line. A type conversion can be a static expression if the operand is itself a static expression, and the target subtype is a static subtype.
Just a clarification: the error message has nothing to do with the type conversion.
It is about having a statement (in this case, an assignment, like i := 3) before the begin keyword.
BTW, I have just improved HAC’s diagnostic for that case.
The object Floaty is initalized (NB: since it is constant, it has to), and yes, this initialization implies some machine code to be emitted. Actually, a lot of action can happen in the declarative part. You can have something like
procedure Do_Something (a, b : Integer) is
M : Matrix_n_n := Some_Function (a, b);
det_M : Real := Det (M);
...
begin
...
end;
I have already had cases where most of the compute action takes place in the declarative part, before the begin of the list of statements! …