0Day Forums
Variadic function in Ada (C - Ada binding)? - Printable Version

+- 0Day Forums (https://0day.red)
+-- Forum: Coding (https://0day.red/Forum-Coding)
+--- Forum: C & C++ (https://0day.red/Forum-C-C)
+--- Thread: Variadic function in Ada (C - Ada binding)? (/Thread-Variadic-function-in-Ada-C-Ada-binding)



Variadic function in Ada (C - Ada binding)? - olenkafyrz - 07-27-2023

I am working on a project which uses **C - Ada language binding**. A function in C will call a function in Ada side. I want to make a variadic function in Ada which can receive a variable number of arguments sent from the C function. I also wanted to send different types of args at the same time like int, char, enums, etc at the same time. Is it possible to have this type of mechanism?


RE: Variadic function in Ada (C - Ada binding)? - Cammie613243 - 07-27-2023

You cannot create a variadic function in Ada. You can simulate a variadic function is a couple of ways.

1. Ada allows you to specify default values for functions and procedures. One need not always specify the values of the default parameters if you want to use the default values.
2. You can define one or more of the parameters as a variant record.


RE: Variadic function in Ada (C - Ada binding)? - honhrjvzkcf - 07-27-2023

You can use 'address or the package System.Address_To_Access_Conversions and 'access (or 'unchecked_access) to generate addresses of each item you want to pass.

type Address_Array is array (positive range <>) of System.address;
function C_Caller(Params : Address_Array) return Integer is begin return 0; end;
X, Y, Z, Result : Integer;
begin
result := C_Caller(Address_Array'(x'address, y'address, z'address));

...then you'll need to pragma import the actual function.


RE: Variadic function in Ada (C - Ada binding)? - tayetnuvx - 07-27-2023

**It is not possible** to call any C variadic function from Ada in a portable way!

One of the reason - some ABIs use special ways/registers to pass float values. This mean C compiler will use this registers, due to it's unknown in advance whether argument is float or not. Ada compiler will not use this registers (since you can't put float parameter in Ada wrapper function declaration). As result you will get crash, stack corruption or any other undefined behavior.

Particularly [AMD64 ABI][1] specifies:
> %rax - with variable arguments passes information
> about the number of vector registers used
>
> %xmm0–%xmm1 - used to pass and return floating
> point arguments

The only portable solution is using C wrapper with fixed number of parameters, then bind it as usual.


[1]:



RE: Variadic function in Ada (C - Ada binding)? - biographees914201 - 07-27-2023

The forthcoming Ada standard Ada 202x is planning to provide support for calling C variadic functions.

You would then be able to write;
<!-- language: ada-lang -->

package C renames Interfaces.C;

procedure Printf (Format : in C.char_array)
with Import => True, Convention => C_Variadic_1, External_Name => "printf";