【问题标题】:How can I encode a property of a value in its type in C?如何在 C 中以类型对值的属性进行编码?
【发布时间】:2014-04-23 18:29:18
【问题描述】:

在一个普通的 C 程序中,我有某些类型的某些值,这些值可能有也可能没有某个属性,并且该属性必须对某些具有此值的用户保持不变。我想知道我们是否/如何使用类型系统在编译时为那些需要它的被调用函数强制执行此属性。

例如,给定这个结构定义:

struct foo {
    bool has_property_bar;
    ...
}

某些函数采用struct foo * 类型的值,has_property_bar 必须为真,因此它们必须通过在运行时测试相关字段来检查此属性(通常使用断言)。

现在我想知道是否可以通过定义一个基于 foo 的新类型来避免这些运行时测试,这表示该值确实具有所需的属性。可能是这样的:

struct bar_compliant_foo {
    struct foo real_foo;
}

struct bar_compliant_foo *set_property_bar(struct foo *f) {
    f->has_property_bar = TRUE;
    return (struct bar_compliant_foo*)f;
}

int do_something_with_compliant_foo(struct bar_compliant_foo *bf) {
    struct foo *f = &bf->real_foo;
    ...
}

这是否适用于玩具程序?除了使用包装原始类型的结构之外,还有其他/更好的方法吗?

【问题讨论】:

  • 我猜你没有任何剩余。将您的 int 升级到更大的尺寸 (int64) 可以让您使用。 OTOH,使用结构体可能会更好,因为除了最简单的数学运算之外,它会对所有操作造成严重破坏。
  • 锁定是什么意思?你想创建对象和继承吗?
  • “这是否适用于玩具程序?”这根本不应该起作用,至少在大多数具有抢先调度的现代操作系统中不起作用。 “除了使用包装原始类型的结构之外,还有其他/更好的方法吗?”是的,使用与调度程序实际交互的锁定机制。特别是对于 C,您应该使用系统提供的互斥锁(或信号量)。 “我想知道我们是否/如何使用类型系统来检查这个属性。”我不确定我们是否对该术语有相同的解释,但是不,C 的类型系统无法帮助您解决并发问题。
  • 这个问题不是关于以任何方式锁定。它是关于能够断言某个属性适用于我的对象,而无需诉诸运行时检查。使用语言的类型系统是在编译时确保对象具有某些属性的一种方法,这就是我在 C 中尝试做的事情。我将删除对“锁定”的引用,因为它似乎具有误导性。跨度>
  • 如何阻止某人拨打set_property_bar(),将属性更改回FALSE,然后拨打do_something_with_compliant_foo()?如果has_property_bar 有时是TRUE,有时是FALSE,显然你不能在编译时检查这个,因为直到程序运行才决定。如果无论调用者想要什么都需要它是真的,那么只需将do_something_with_compliant_foo() 的第一行设置为f->has_property_bar = TRUE; 或类似的,你就可以保证它会是。

标签: c types struct compile-time


【解决方案1】:

C 与高级编程语言一样裸露且接近芯片。 C 类型系统反映了这个想法:数据类型只是一堆可以同时更改的字节。即,双精度是一个 8 字节的数组,您可以同时更改它以表示浮点数。这就是 C 类型系统所能达到的程度。

如果您想在编译时强制执行某些特定的程序属性,例如,将布尔变量设置为 True,您必须转移到另一种编程语言。您可以尝试 C++ 与一些巫毒魔法模板元编程。但是根据您提出的问题类型,我猜您已经具备一些强静态类型编程语言的背景。

【讨论】:

  • 在这种情况下,我没有选择将现有的大型代码库切换到另一种语言的选项,因此我尝试使用 C。顺便说一句,现在 C 编译器在您混合指向不同的指针时会抱怨struct 类型,这已经是一定程度的严格性了,所以我想知道更聪明的人是否设法从语言中挤出了我在这里寻找的那种特性。
猜你喜欢
  • 1970-01-01
  • 2017-01-23
  • 2018-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-14
相关资源
最近更新 更多