Consider the following simple function in c++...
int function(int *a, int x)
{
return x*x;
}
My question is: How to translate the above function into an ada function as I can't write the pointer.
Thanks in advance
Consider the following simple function in c++...
int function(int *a, int x)
{
return x*x;
}
My question is: How to translate the above function into an ada function as I can't write the pointer.
Thanks in advance
You can pass pointers (access types) into Ada functions or procedures but you normally don't want to.
The usual reason for passing a pointer into a C function is to allow the function to modify the thing pointed at.
C doesn't have any better way of letting you do that; Ada does.
Instead of passing values or pointers (or in C++, references), you pass objects with appropriate modes : In, Out, In Out, describing how the argument is used.
So you probably want to write
function My_Func (a : in out Integer;
x : in Integer) return integer is
begin
return x * x;
end My_Func;
but there are several problems:
out
or in out
argument from a function; they are reserved for procedures (which C would call "void functions")The last one may look odd : Ada's functions are ideally functions in the mathematical sense, not the C sense of being "any old subprogram". That is, they accept arguments, process them without modifying them or anything else and return a result. These are called pure functions and like proper operators you can optimise around them much more safely than is otherwise true.
Ada unlike some stricter languages, does allow impure functions which may modify state (e.g. updating the seed in a random generator on each call) and as of 2012 also allows out
and in out
parameters; a legitimate use would be to update an "OK" flag in a series of operations like file reads.
So how do we normally use Out
parameters? In a procedure, which like a statement, can modify things (assignment) or change state. So if you meant to use the argument a
you might write:
procedure My_Proc (a : out Integer;
x : in Integer) is
begin
a := x * x;
end My_Proc;
Think of a function as an abstraction over an expression, while a procedure abstracts over a statement. (This leads to some obvious refactorings; replace expression with function, statement or block with procedure).
If this doesn't actually answer the question and you think you might really need pointers, add a comment or update the question.
Further to Brian’s answer, you might declare
type Arr is array (Integer range <>) of Integer;
(that’s to say, all instances of Arr
are arrays containing Integer
s indexed by Integer
s, but different instances can have different bounds). There are three common ways of writing subprograms that use Arr
s.
If you only want to read the values, use (or default to) in
mode:
function Sum (A : Arr) return Integer
is
Total : Integer := 0;
begin
for J in A'Range loop
Total := Total + A (J);
end loop;
return Total;
end Sum;
If you don’t care what the previous contents were, use out
mode:
procedure Initialize (A : out Arr; To : Integer)
is
begin
for J in A'Range loop
A (J) := To;
end loop;
end Initialize;
If you want to update the previous contents, use in out
mode:
procedure Multiply (A : in out Arr; By : Integer)
is
begin
for J in A'Range loop
A (J) := A (J) * By;
end loop;
end Multiply;
Sticking to Ada 2005, functions aren’t allowed to have out
or in out
parameters, but (as NWS said) you can use access
mode:
function Divide_And_Sum (A : access Arr; By : Integer) return Integer
is
Sum : Integer := 0;
begin
for J in A'Range loop
A (J) := A (J) / By;
Sum := Sum + A (J);
end loop;
return Sum;
end Divide_And_Sum;
but then you need to declare the actual array aliased
:
T : aliased Arr := (0, 1, 2, 3, 4, 5);
and pass its ’Access
in the call:
New_Sum := Divide_And_Sum (T'Access, 2);
In Ada, Pointers are not implicitly defined (by using a *), you need to define their types explicitly like below:
type Int_Ptr is access Integer;
function My_Func (A : in Int_Ptr;
X : in integer) return Integer is
begin
return X*X;
end My_Func;
Then you can produce a function exactly like the C++ one you supplied. How this helps your problem im not sure. @Brian Drummond has a useful discussion of this in his answer.