【问题标题】:Casting between structs?结构之间的转换?
【发布时间】:2008-11-06 08:33:01
【问题描述】:

我正在开发一个代码库,其中我们有几种可配置的类型。其中一种类型是 64 位整数。当我们为没有原生 64 位整数类型的平台进行编译时,我们使用类似于

的结构简单地表示 64 位整数
typedef struct {
    unsigned int hi, lo;
} int64;

为了让这个类型有用,所有常用的操作都定义为函数,比如

int64 int64_add(int64 x, int64 y);

在原生 64 位整数类型可用的平台上,这些操作看起来很简单

#define int64_add(x, y) ((x) + (y))

不管怎样,继续这个问题。我正在实现一些关于时间的功能,我想使用 64 位整数来表示我的时间:

typedef int64 mytime;

我还希望 int64 类型可用的所有常见操作也可用于我的时间类型:

#define mytime_add(x, y) (mytime) int64_add((int64) (x), (int64) (y))

问题在于 C 中不允许类型 mytime 和 int64 之间的转换(据我所知)。有什么方法可以做到这一点,而不必重新实现 mytime 类型的所有 add、sub、mul、div 等函数?

当然,一种选择是永远不要使用 mytime typedef,而在需要表示时间的任何地方都使用 int64。问题在于我不确定我是否总是想将时间表示为 64 位整数。然后还有可读代码的问题...... :-)

【问题讨论】:

    标签: c


    【解决方案1】:

    因为您使用的是 typedef,所以您根本不需要强制转换。 C 中的 Typedef 不会创建不同的类型,只会创建另一种类型的别名。编译器不区分它们。只需将 mytime_add 函数编写为:

    #define mytime_add(x, y) int64_add((x), (y))
    

    或者如果您的 C 编译器足以进行内联:

    mytime mytime_add(mytime x, mytime y) { return int64_add(x, y); }
    

    【讨论】:

    • 为什么不只是#define mytime_add int64_add 而不用担心宏参数评估,还可以获得能够使用mytime_add 作为函数指针的好处?
    【解决方案2】:

    你真的需要演员吗? gcc 正在编译以下示例,没有任何抱怨:

    
    typedef struct int64 int64;
    
    struct int64
    {
        unsigned int hi, lo;
    };
    
    typedef int64 mytime;
    
    int64
    add_int64(int64 a, int64 b)
    {
        int64 c;
        /* I know that is wrong */
        c.hi = a.hi + b.hi;
        c.lo = a.lo + b.lo;
    
        return c;
    }
    
    int
    main(void)
    {
        mytime a = {1, 2};
        mytime b = {3, 4};
        mytime c;
    
        c = add_int64(a, b);
    
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      你可以试试:

      #define mytime int64
      

      而不是 typedef。

      看起来它会为您提供所需的透明转换和可维护性。

      【讨论】:

        【解决方案4】:

        看看 stdint.h 头文件。它包含 int64_t、uint64_t 等。这是标准且可移植的方式,您将无需实现数学函数:)。

        【讨论】:

        • 没有帮助,因为只有当编译器支持 64 位类型时,int64_t 才会存在。
        【解决方案5】:

        是的,所以我使用 typedef 并且没有强制转换。工作正常。尽管显式强制转换不会编译而隐式强制转换会编译,但这似乎很奇怪。如果由于编译器认为这两种类型是相同的类型,所以隐式强制转换根本不是强制转换,那么人们会认为在进行显式强制转换时同样的推理会起作用......

        【讨论】:

        • (int)someIntVar; 编译吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-15
        • 2014-12-09
        • 1970-01-01
        相关资源
        最近更新 更多