por*_*ton 3 enums ada type-conversion
让在 C 代码中定义:
typedef enum { A=1, B=2 } option_type;
void f(option_type option);
让我们也有 Ada 代码:
类型 Option_Type 是 (A, B); 对于 Option_Type'Size 使用 Interfaces.C.int'Size; 对于 Option_Type 使用 (A=>1, B=>2); X: Option_Type := A;
以下哪个代码是正确的(相应地为 RM)?
-- 第一个代码
宣布
程序 F(选项:Option_Type)
使用导入,约定=> C,外部名称=>“f”;
开始
F(X);
结尾;
或者
-- 第二个代码
宣布
过程 F(选项:Interfaces.C.unsigned)
使用导入,约定=> C,外部名称=>“f”;
函数 Conv 是新的 Ada.Unchecked_Conversion(Option_Type, Interfaces.C.unsigned);
开始
F(转化率(X));
结尾;
我认为第一个和第二个 Ada 片段都是正确的,但我不确定。
两者都不是 100% 正确的。
在 C 中:
typedef enum { A=1, B=2 } option_type;
Run Code Online (Sandbox Code Playgroud)
在阿达:
type Option_Type is (A, B);
for Option_Type'Size use Interfaces.C.int'Size;
for Option_Type use (A=>1, B=>2);
Run Code Online (Sandbox Code Playgroud)
Ada 代码假定 C 类型与 Coption_type具有相同的大小int。您的第二个代码段假定它与 C 具有相同的表示形式unsigned int。
C 标准不支持这两种假设。
每个枚举类型应与
char、有符号整数类型或无符号整数类型兼容。类型的选择是实现定义的,但应能够表示枚举的所有成员的值。
因此,C 类型option_type可以窄至 1 个字节或与支持的最宽整数类型(通常为 8 个字节)一样宽,并且它可以是有符号的或无符号的。C 将枚举常量的值限制在 type 的范围内int,但这并不意味着类型本身与int-- 或与unsigned int.
如果您了解正在使用的特定 C 编译器的特征(短语“实现定义”意味着必须记录这些特征),那么您可以依赖这些特征——但您的代码将是非-便携的。
我不知道有任何完全可移植的方式来定义与给定 C 枚举类型兼容的 Ada 类型。(我已经离开 Ada 很长时间了,所以我可能会遗漏一些东西。)
我能想到的唯一可移植方法是编写一个 C 包装函数,它接受一个指定整数类型的参数并调用f(). option_type然后由 C 编译器处理从整数类型到整数类型的转换,包装器向 Ada 公开一个带有已知类型参数的函数。
void f_wrapper(int option) {
f(option); /* the conversion from int to option_type is implicit */
}
Run Code Online (Sandbox Code Playgroud)