【问题标题】:Interfacing Ada enumerations and C enums接口 Ada 枚举和 C 枚举
【发布时间】:2014-08-17 20:09:21
【问题描述】:

让在C代码中定义:

typedef enum { A=1, B=2 } option_type;

void f(option_type option);

让我们也有 Ada 代码:

type 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”;
开始
   前锋(X);
结束;

-- 第二个代码

声明
   程序 F(选项:Interfaces.C.unsigned)
      带导入,约定=>C,外部名称=>“f”;
   函数 Conv 是新的 Ada.Unchecked_Conversion(Option_Type, Interfaces.C.unsigned);
开始
   F(转换(X));
结束;

我认为第一个和第二个 Ada 片段都是正确的,但不确定。

【问题讨论】:

    标签: enums ada type-conversion


    【解决方案1】:

    两者都不是 100% 正确的。

    在 C 中:

    typedef enum { A=1, B=2 } option_type;
    

    在艾达:

    type Option_Type is (A, B);
    for Option_Type'Size use Interfaces.C.int'Size;
    for Option_Type use (A=>1, B=>2);
    

    Ada 代码假定 C 类型 option_type 与 C int 具有相同的大小。您的第二个 sn-p 假定它与 C unsigned int 具有相同的表示形式。

    C 标准都不支持这两种假设。

    引用N1570 草案,第 6.7.2.2 节,第 4 段:

    每个枚举类型都应与 char 兼容,这是一个有符号的 整数类型,或无符号整数类型。类型的选择是 实现定义,但应能够表示 枚举所有成员的值。

    因此,C 类型 option_type 可以窄至 1 个字节,也可以宽至支持的最宽整数类型(通常为 8 个字节),它可以是有符号的或无符号的。 C 将枚举常量的值限制在int 类型的范围内,但这并不意味着该类型本身与intunsigned int 兼容。

    如果您了解正在使用的特定 C 编译器的特性(短语“实现定义”意味着必须记录这些特性),那么您可以依赖这些特性——但您的代码正在运行不可携带。

    我不知道有任何完全可移植的方式来定义与给定 C 枚举类型兼容的 Ada 类型。 (我已经离开 Ada 很长时间了,所以我可能会遗漏一些东西。)

    我能想到的唯一可移植方法是编写一个 C 包装函数,该函数接受指定整数类型的参数并调用 f()。然后由 C 编译器处理从整数类型到 option_type 的转换,并且包装器将带有已知类型参数的函数公开给 Ada。

    void f_wrapper(int option) {
        f(option); /* the conversion from int to option_type is implicit */
    }
    

    【讨论】:

    • @porton:不,自 1989 年 ANSI 标准以来,C 标准在这方面没有显着变化。枚举 constant 的类型为 int。枚举 type 与某些实现定义的整数类型兼容。对于具有少量值的枚举类型,编译器可能会合理地将其设为 1 个字节。
    • @AlexisWilke:不,enum 的默认表示在 C 或 C++ 中都不是 int,并且您提到的链接不支持您的主张。 C 不允许定义与给定枚举类型兼容的类型。
    • @porton:with Conversion => C 很可能会起作用,只要您使用它将 Ada 枚举类型匹配到 C 枚举类型。 (我对 Ada RM 的研究还不够仔细,无法确定这一点。)只是不要假设 C 枚举类型对应于任何特定的 C 整数类型——除非你愿意接受不可移植的代码。
    • @KeithThompson:约定,而不是转换
    • @KeithThompson,这对于 C 来说可能是正确的。在 C++ 中,如果所有枚举值都适合 int,则默认为 int。我提供的链接确实提到了这一点。
    猜你喜欢
    • 1970-01-01
    • 2017-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    相关资源
    最近更新 更多