【问题标题】:C: make a type incompatible with any other typesC:使一个类型与任何其他类型不兼容
【发布时间】:2014-09-15 16:12:21
【问题描述】:

在 C 中,或者至少在 GCC 中,是否有某种方法可以使(使用 typedef)成为与任何其他类型不兼容的类型?

例如,您制作:

typedef UINT UID;
typedef UINT AGE;

UID user_id;
AGE user_age;

你可以看到这两种类型都是unsigned int(我把它命名为UINT)。

可以计算出user_id + user_age。

但是,您要确保 UID 和 AGE 永远不会混合。

这就是我想要的!

这个想法是为了代码的安全性和正确性,为某些类型指定一些限定符/属性。

例如,混合它们的唯一方法是将两者都转换为 UINT,或将 user_age 转换为 UID。

C 语言可能非常令人困惑,有时我们会花几个小时来发现存在愚蠢的错误只是因为您使用了错误的值作为参数,因为变量具有相似的名称......而且编译器显然永远不会抱怨,因为他们有相同的类型。

我在 GCC 手册中没有找到任何属性,但我将在邮件列表中请求它。

我只是想知道如何(我知道没有,我真正的问题是为什么标准和编译器不提供这个,因为我认为它非常有用并且相对之一在编译器端实现的最简单的事情)在类型(以及变量)上指定一些属性,以告诉编译器 TYPE 不应该与任何其他混合,除非显式转换为它。 所以这里真正的问题是: - 为什么这是个坏主意? (为什么没有编译器考虑它?) - 如果这个 GCC 属性存在,你还会使用它吗? 哦...在我看来,我会在这里和那里使用它,只需将此属性放在几乎所有类型定义中,然后就可以编程了;在第一次编译时会检测到很大一部分错误 - 以错误的顺序传递参数,在大而复杂的计算中使用错误的变量......

对不起,我的英语不好。

【问题讨论】:

  • 使用struct 和不同的标签来创建不兼容的类型。
  • 吹毛求疵:“你可以看到[e]这两种类型都是无符号整数。”它们不是。两者都是UINT 类型,无论这可能被定义为什么。 UINT 不是 C 标准定义的类型。
  • 这个功能叫做“strong typedef”,在搜索网页时应该会给你一些提示。
  • 说“两种类型”都是unsigned int 不太准确。假设UINTunsigned int 的类型定义,这里只有一种类型。那一种类型恰好有至少 4 个不同的名称:unsigned intUINTUIDAGEtypedef 不会创建新类型,兼容或其他方式;它只是为现有类型创建一个新名称。

标签: c gcc compiler-warnings


【解决方案1】:

假设 UINT 被定义为某种类型,您可以为它们创建 typedef 以使其不兼容。下面的代码说明了如何初始化和操作它们。

typedef struct { UINT id; } UID;
typedef struct { UINT age; } AGE;

UID user_id = { 1234 }; /* Example of initialization of a struct */
AGE user_age = { 23 };

int main()
{
    UINT add;
    user_age.age = 25; /* example of assignment */
    add = user_id + user_age; /* Example of compile error */

    return 0;
}

也有一些缺点。您不能将结构与运算符(+、-、/、* 等)一起使用。 IE。您不能将两个结构添加在一起。因此,这是行不通的:

AGE user1age = { 25 };
AGE user2age = { 23 };
UINT totage = user1age + user2age;

您必须这样做并在结构中显式添加年龄值:

AGE user1age = { 25 };
AGE user2age = { 23 };
UINT totage = user1age.age + user2age.age;

【讨论】:

    【解决方案2】:

    使用structs:

    typedef struct 
    {
      unsigned int uid;
    } UID;
    
    typedef struct
    { 
      unsigned int age;
    } AGE;
    
    UID user_id;
    AGE user_age;
    

    【讨论】:

      猜你喜欢
      • 2022-01-11
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 2021-07-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多