Question

Is there a way to ignore return values in Ada functions?

I have a function which imports from an Intrinsic.

subtype int32 is Interfaces.Interger_32;

function Intrinsic_Sync_Add_And_Fetch
    (P : access int32; I : int32) return int32;

pragma Import(
            Intrinsic, 
            Intrinsic_Sync_Add_And_Fetch, 
            "__sync_add_and_fetch_4");

If I want to use this in a procedure, I need to accept the return value or I will get a compiler error:

cannot use function Intrinsic_Sync_Add_And_Fetch in procedure call.

But, if I create a variable that simply takes the return value of the function and is never used then I get compiler warnings. Obviously, I'd rather avoid those.

I can't very well assign the value back to the value I'm adding to; this would undermine the point of the add operation being atomic.

There is the option of taking the value and doing something with it, like:

val := Intrinsic_Sync_Add_And_Fetch(...);
if val := 0 then null; end if;

It forces the code to compile without errors or warnings, but it seems stupid to me. How can I "get around" this language feature and safely ignore the return value?

Edit: What is __sync_add_and_fetch_4?

This is a built-in atomic operation available on Intel CPUs. As such, part of my Autoconf/Automake process would be deciding if the operation is available, and use a fallback implementation, which involves a critical section, if it's not.

You can read about this and similar operations in GCC's section on atomic builtins.

The __sync_add_and_fetch_4 does pretty much exactly what it says. In C, it would look something like this:

int32_t __sync_add_and_fetch_4(int32_t *ptr, int32_t value) {
    *ptr += value;
    return *ptr;
}

So it's an atomic addition operation, which returns the result of the addition. Basically, it's an atomic += operator. The _4 means that it takes a 4-byte integer.

Edit: I understand that I could probably just switch off that particular compiler warning, but that always feels dirty to me. If there's a solution available that allows me to continue using -Wall -Werror then I'd love to see it.

Was it helpful?

Solution

declare
   dummy : constant return_type := my_function;
   pragma Unreferenced (dummy);
begin null; end;

or write a wrapper procedure.

OTHER TIPS

If you never want to reference the return value, why not declare the subprogram as a procedure? The value is going to be returned in a register, so throwing it away won’t cause a lot of grief. (I stand to be corrected on this one!)

subtype int32 is Interfaces.Integer_32;

procedure Intrinsic_Sync_Add_And_Fetch
    (P : access int32; I : int32);

pragma Import(
            Intrinsic, 
            Intrinsic_Sync_Add_And_Fetch, 
            "__sync_add_and_fetch_4");

You said you're only targeting the GNAT compiler. The GNAT User's Guide says:

Note that a special exemption applies to variables which contain any of the substrings DISCARD, DUMMY, IGNORE, JUNK, UNUSED, in any casing. Such variables are considered likely to be intentionally used in a situation where otherwise a warning would be given, so warnings of this kind are always suppressed for such variables.

So the simplest solution to your problem is :

unused := Intrinsic_Sync_Add_And_Fetch(...);

Though you might want to wrap that in a procedure if you are going to use it more than a couple of times :

procedure Intrinsic_Sync_Add_And_Fetch(P : access int32; I : int32) is
   unused : int32;
begin
   unused := Intrinsic_Sync_Add_And_Fetch(P : access int32; I : int32);
end Intrinsic_Sync_Add_And_Fetch;

i don't know of any way to ignore the return value of a function in Ada: the language has been especially designed to force you to store those return values.

personally, i would store the return value and ignore any warning regarding the use of the variable. anyway, the said warning is quite strange since the variable is indeed used to store the return value.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top