避免警告 8 位 Ada 布尔返回类型,使用 Char

Avoiding warning 8-bit Ada Boolean return type, use Char

提问人:Brinck 提问时间:2/21/2023 更新时间:2/21/2023 访问量:177

问:

我一直在努力清理迂腐代码上的警告,我们将警告视为错误。我有 Ada 和 C++ 之间的接口代码,如下所示:

Ada manager.ads:

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

C++ Adamanager.cpp:

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

C++ Adamanager.h:

extern "C" bool Foo(int32_t ID);

C++ 管理器.cpp:

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

C++ manager.h

static bool Bar(int32_t ID);

manager.ads 的 gcc -c 输出:

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 位?

C++ ADA 外部编译 指示

评论

0赞 Jim Rogers 2/21/2023
C++ bool 类型中包含的值将为 0 表示 false,1 表示 true。C++ 将 bool 类型定义为无符号的 8 位值,该值干净地映射到包接口中定义的 char 类型。

答:

4赞 Jeffrey R. Carter 2/21/2023 #1

这种方法存在许多问题。首先,应使用 C 类型声明 C 函数。虽然有声明 和 的标准标头,但由于您不包含它们,因此您应该将它们替换为相应的 C 类型,可能是 和 :boolint32_tcharint

extern "C" char Foo (int ID);

其次,由于您的函数被声明为 C,而不是 C++,因此您应该使用约定 C 而不是 CPP 导入它。(在 C++ 周围声明这样的 C 包装器的全部原因是为了避免直接与 C++ 接口的问题。

第三,使用非约定 C 类型(如 Integer 和 Boolean)与 C 接口是一个坏主意。它可能会起作用,但不能保证继续与编译器的未来版本一起使用。最好使用 Interfaces.C 中的适当类型。

第四,您不能保证返回的值将限制为 0 或 1,因此您需要将其视为 C 的 0 或非 0。

有了这一切,你的 Ada 就会成为

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;

尽管您可能希望在 Ada 端对 ID 使用 Integer 以外的类型。

这应该可以正常工作,消除警告,并提供一些针对编译器更改的保护。

评论

0赞 Brinck 2/23/2023
我假设如果我只能使用 Ada95,则存在一些限制。例如,我仍然必须使用 Pragma Import,是吗?
0赞 Jeffrey R. Carter 2/25/2023
如果使用 Ada 95,那么您没有方面,必须使用编译指示。由于引用子程序的杂注往往适用于具有给定名称的所有本地子程序,因此您可能需要对导入的 Foo 版本使用另一个名称。