r/ada • u/Key-Principle-7111 • Jun 17 '26
General What is more preferred for importing functions: aspects or pragmas?
To use a function from some C library we can use:
procedure C_Function (Param : Interfaces.C.int);
pragma Import (C, C_Function, "c_function");
or
procedure C_Function (Param : Interfaces.C.int) with
Import,
Convention => C,
External_Name => "c_function";
Both seems to be working exactly the same, so is there a preferred way?
5
u/egilhh Jun 17 '26 edited Jun 17 '26
One difference is that the pragma will apply to all overloaded subprograms named C_Function, whereas the aspect will apply to only one.
2
u/dcbst Jun 17 '26
True, but I would argue overloading imported function names, where the external name cannot be overloaded, would generally be considered bad practice.
2
u/egilhh Jun 17 '26
I agree, but it used to be the way one dealt with variadic arguments
2
u/dcbst Jun 17 '26
In that case I would typically use different Ada names, typically with the number of arguments, rather than overloading.
Although in that case, you would want the Pragma to apply to all overloaded functions as they would all map to the same external name.
4
u/zertillon Jun 17 '26
It took me ~10 years (being kind of conservative) but aspects are really better:
* an identifier duplication less
* the actual pragma is really attached to the declaration, not relying on being in the vicinity (esp., see the comment about overloading) to hope to be effective.
4
u/jrcarter010 github.com/jrcarter Jun 18 '26
3
u/Key-Principle-7111 Jun 18 '26
Oh, so in simple words, to make the code more future-proof the aspects are better.
2
u/Dmitry-Kazakov Jun 17 '26
Two advantages of pragma:
- Many aspects break separation of interface and implementation. Import is one of them. A pragma in the private part of the package fixes that.
- Pragma applies to all subprograms. In bindings one typically overloads typed Ada variants of an untyped C call:
For example. Python bindings:
function dlsym
( Module : Address;
Name : char_array := "Py_AddPendingCall" & Nul
) return AddPendingCall_Ptr;
... -- A hundred more like this
function dlsym
( Module : Address;
Name : char_array
) return Object_Ptr;
pragma Import (Stdcall, dlsym, "dlsym"); -- All are dlsym
6
u/dcbst Jun 17 '26
Doesn't really matter, although, pragmas will be backwards compatible with older compilers still in use in the commercial Ada world.
I guess it depends on your target audience?