【问题标题】:What's the benefit of encapsulating only one basic field into a struct in C?在 C 中只将一个基本字段封装到一个结构中有什么好处?
【发布时间】:2012-05-02 07:34:46
【问题描述】:

我看到了一些这样的 C 代码:

// A:
typedef uint32_t in_addr_t;
struct in_addr { in_addr_t s_addr; };

我总是喜欢这样:

// B:
typedef uint32_t in_addr;

所以我的问题是:在 A 和 B 中做这件事有什么区别/好处?

【问题讨论】:

    标签: c struct typedef


    【解决方案1】:

    这是一个引入类型安全的层,它可以为“未来的扩展”提供帮助。

    前者的一个问题是,很容易将 typedefed 内置函数表示的类型的值“转换”为其他几种类型或 typedefed 内置函数中的任何一种。

    考虑:

    typedef int t_millisecond;
    typedef int t_second;
    typedef int t_degrees;
    

    对比:

    // field notation could vary greatly here:
    struct t_millisecond { int ms; };
    struct t_second { int s; };
    struct t_degrees { int f; };
    

    在某些情况下,使用符号会更清楚一些,编译器也会禁止错误的转换。考虑:

    int a = millsecond * second - degree;
    

    这是一个可疑程序。使用 typedefed ints,这是一个有效的程序。使用结构,它的格式不正确——编译器错误需要你更正,你可以明确表达你的意图。

    使用 typedef,可以应用任意算术和转换,并且它们可能会在没有警告的情况下相互分配,这可能会成为维护的负担。

    同时考虑:

    t_second s = millisecond;
    

    这也是一个致命的转变。

    这只是工具箱中的另一个工具——请自行决定使用。

    【讨论】:

    • 为了安全,你的意思是为了避免一些错误的类型转换?对于扩展,我更愿意将一个简单的 typedef 更改为一个结构,当我真的想要这样做时。
    • +1 是的,但我不确定他是否会理解没有示例! :)
    • @paladin_t:如果您将浮点值分配给 uint32_t,则会出现一些警告,请执行分配。然而,这对于结构来说是不可能的。
    • @paladin_t 我认为“为了未来的扩展”不仅仅是“扩展价值”而是“扩展收集的数据类型”,即能够拥有一个开始扩展结构的 API维护与请求关联的元数据,而不需要更改接口本身。我还使用了“结构的单个成员”来允许我在戳我提供的接口的代码中添加/删除不可见的调试数据。
    • @paladin_t 已扩展。不是类型转换,可接受的隐式转换,因为基础类型相同。
    【解决方案2】:

    贾斯汀的回答基本上是正确的,但我认为需要一些扩展:
    编辑:贾斯汀大大扩展了他的答案,这使得这个答案有些多余。

    类型安全 - 您希望为您的用户提供操作数据的 API 函数,而不是让它仅仅将其视为整数。将字段隐藏在结构中会更难以错误的方式使用它,并将用户推向正确的 API。

    为了未来的扩展 - 也许未来的实施想要改变一些事情。也许添加一个字段,或者将现有字段分成 4 个字符。使用结构体,无需更改 API 即可完成。

    您的有什么好处?如果实现发生变化,您的代码不会中断。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-03
      • 2010-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多