Избегайте предупреждающего 8-битного типа возвращаемого значения Ada Boolean, используйте Char

Я работаю над очисткой предупреждений от педантичного кода, и мы рассматриваем предупреждения как ошибки. У меня есть код интерфейса между Ada и C++, который выглядит так:

Ада менеджер.объявления:

function Foo(ID_Type : in Integer) return Boolean;
pragma Import(CPP, Foo, "Foo");

С++ Адаманагер.cpp:

extern "C" bool Foo(int32_t ID)
{
  return Manager::GetManager()->Bar(ID);
}

С++ Адаманагер.h:

extern "C" bool Foo(int32_t ID);

С++ менеджер.cpp:

bool Manager::Bar(int32_t ID)
{
   //function body
   return answer;
}

С++ менеджер.h

static bool Bar(int32_t ID);

Вывод gcc -c для manager.ads:

warning: return type of "Foo" is an 8-bit Ada Boolean
warning: use appropriate corresponding type in C (e.g. char)

У меня куча таких случаев.

Чтобы избавиться от предупреждений, мне нужно заменить все логические значения на char или какой-либо другой 8-битный тип, а затем выполнить явное преобразование типов в основном коде Ada? Почему компилятор решил, что логическое значение должно быть 8-битным?

Значение, содержащееся в типе bool C++, будет равно 0 для false и 1 для true. C++ определяет тип bool как 8-битное значение без знака, которое четко отображается на тип char, определенный в пакете interfaces.c.

Jim Rogers 21.02.2023 05:43
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

При таком подходе возникает ряд проблем. Во-первых, ваша функция C должна быть объявлена ​​с использованием типов C. Хотя есть стандартные заголовки, которые объявляют bool и int32_t, поскольку вы их не включаете, вы должны заменить их соответствующими типами C, возможно, char и int:

extern "C" char Foo (int ID);

Во-вторых, поскольку ваша функция объявлена ​​как C, а не C++, вы должны импортировать ее по соглашению C, а не CPP. (Единственная причина объявления таких C-оболочек вокруг C++ состоит в том, чтобы избежать проблем прямого взаимодействия с C++.)

В-третьих, плохой идеей является взаимодействие с C с использованием неконвенционных типов C, таких как Integer и Boolean. Это может работать, но не гарантируется продолжение работы с будущими версиями компиляторов. Лучше использовать соответствующие типы из Interfaces.C.

В-четвертых, у вас нет гарантии, что возвращаемое значение будет ограничено 0 или 1, поэтому вам нужно обрабатывать его так же, как это делает C, 0 или не 0.

При всем этом ваша Ада становится

with Interfaces.C;

function Foo (ID : in Integer) return Boolean is
   function Foo (ID : in Interfaces.C.int) return Interfaces.C.unsigned_char
   with Import, Convention => C, External_Name => "Foo";

   use type Interfaces.C.unsigned_char;
begin -- Foo
   return Foo (Interfaces.C.int (ID) ) /= 0;
end Foo;

хотя вы, вероятно, захотите использовать тип, отличный от Integer, для идентификаторов на стороне Ada.

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

Я предполагаю, что есть некоторые ограничения, если я могу использовать только Ada95. Например, тогда мне все равно придется использовать Pragma Import, да?

Brinck 22.02.2023 23:27

Другие вопросы по теме