Игнорировать возвращаемые значения функции Ada - PullRequest
4 голосов
/ 09 февраля 2012

Есть ли способ игнорировать возвращаемые значения в Ada функциях?

У меня есть функция, которая импортирует из встроенного.

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");

Если я хочу использовать это в процедуре, мне нужно принять возвращаемое значение, или я получу ошибку компилятора:

cannot use function Intrinsic_Sync_Add_And_Fetch in procedure call.

Но, если я создаю переменную, которая просто принимает возвращаемое значение функции и никогда не используется, я получаю предупреждения компилятора. Очевидно, я бы предпочел избежать этого.

Я не очень хорошо могу присвоить значение назад значению, к которому добавляю; это подорвало бы точку атомарной операции add.

Существует возможность взять значение и сделать с ним что-то , например:

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

Это заставляет код компилироваться без ошибок или предупреждений, но мне кажется глупым. Как я могу "обойти" эту языковую функцию и безопасно проигнорировать возвращаемое значение?

Редактировать: Что такое __sync_add_and_fetch_4?

Это встроенная элементарная операция, доступная на процессорах Intel. Таким образом, часть моего процесса Autoconf / Automake будет решать, доступна ли операция, и использовать альтернативную реализацию, которая включает критический раздел, если это не так.

Об этой и аналогичных операциях вы можете прочитать в разделе GCC по атомарным встроенным функциям .

__sync_add_and_fetch_4 делает в точности то, что говорит. В C это будет выглядеть примерно так:

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

Так что это атомарная операция сложения, которая возвращает результат сложения. По сути, это атомарный оператор +=. _4 означает, что требуется 4-байтовое целое число.

Редактировать : Я понимаю, что, возможно, я мог бы просто отключить это конкретное предупреждение компилятора, но это всегда кажется мне грязным. Если есть решение, позволяющее мне продолжать использовать -Wall -Werror, я бы с удовольствием его увидел.

Ответы [ 4 ]

4 голосов
/ 09 февраля 2012
declare
   dummy : constant return_type := my_function;
   pragma Unreferenced (dummy);
begin null; end;

или напишите процедуру-оболочку.

3 голосов
/ 19 марта 2015

Вы сказали, что нацелены только на компилятор GNAT. Руководство пользователя *1001* GNAT гласит:

Обратите внимание, что специальное исключение применяется к переменным, которые содержат любую из подстрок DISCARD, DUMMY, IGNORE, JUNK, UNUSED в любом корпусе.Считается, что такие переменные могут быть преднамеренно использованы в ситуации, когда в противном случае будет выдано предупреждение, поэтому предупреждения такого рода всегда подавляются для таких переменных.

Итак, самое простое решение вашей проблемы:

unused := Intrinsic_Sync_Add_And_Fetch(...);

Хотя вы, возможно, захотите обернуть это в процедуру, если собираетесь использовать ее несколько раз:

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;
3 голосов
/ 09 февраля 2012

Если вы никогда не хотите ссылаться на возвращаемое значение, почему бы не объявить подпрограмму как процедуру? Значение будет возвращено в регистр, поэтому его выбрасывание не вызовет много горя. (Я исправлюсь!)

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");
0 голосов
/ 09 февраля 2012

Я не знаю ни одного способа игнорировать возвращаемое значение функции в Ada: язык был специально разработан, чтобы заставить вас хранить эти возвращаемые значения.

лично, я бы сохранил возвращаемое значение и проигнорировал бы любое предупреждение относительно использования переменной. в любом случае, упомянутое предупреждение довольно странно, поскольку переменная действительно используется для хранения возвращаемого значения.

...