是否可以在C语言中添加类型推断?

时间:2011-06-28 22:26:55

标签: c compiler-construction functional-programming type-inference

假设我们创建了C的重新实现,唯一的区别在于 推断出这些类型。存储类和修饰符仍然需要 给定(const,static,restrict等),让我们把注意力限制在单身 文件C程序暂时。可以吗?有什么专业 障碍?

关于什么可能导致类型推断出现问题的一些想法

    具有相同字段名称的
  • 结构需要手动消除歧义
  • 对于具有相同字段名称的联盟
  • 强制转换可能需要一个“from”注释,类似于

    var i = (uint32_t -> uint64_t) *some_pointer;
    

这些问题需要一些用户注释,但不应该这样 繁琐,是否有一些将这个想法从水中吹出的杀手问题?

编辑:为了澄清,我不是在谈论添加泛型或参数多态,只是对现有C类型进行类型推断。

编辑2014:任何对此概念感兴趣的人都可能需要查看Rust

6 个答案:

答案 0 :(得分:10)

GCC 5.1支持:

答案 1 :(得分:6)

C会自动提升某些类型,这会使事情复杂化。但是为了可行,你需要与C存在一些额外的差异:现在,标准仍然在某种程度上支持传统的K& R C程序,并且要求以特定方式处理未指定的类型。 (例如,在没有原型的情况下,参见函数参数的规则。过去也可以使用 no 类型指定函数和变量,它们将默认为(int) 。(如何使用变量?仅限存储类。static foo;))在添加新的隐含类型机制之前,必须删除所有这些遗留类型处理。

答案 2 :(得分:4)

要推断多态函数的类型,需要对C类型系统进行大幅扩展。实施例

length(p) {
  if (p == NULL) return 0;
  else return 1 + length(p->next);
}

此代码必须处理指向具有next字段的结构(或联合)的任何指针。您可以检查行多态,但至少,您的新类型系统必须比C类型系统更具表现力。

另一个迫切的问题是重载+操作。它默认是什么类型的?你想让它在任何数字类型上重载,比如Haskell或C ++吗?如果是这样,那么类型系统会有更大的扩展。

更大的教训是不要这样做。 C(作为一种语言,除了C中提供的许多优秀API之外)的优点是

  • 您可以完全控制数据的表示形式。
  • 任何检查源代码的人都可以轻松预测时间和空间成本。

这个议程与多态性并不真正兼容,而多态性是类型推断的主要好处。如果您想要类型推断,请选择支持它的许多优秀语言之一(F#,Haskell,ML)。

答案 3 :(得分:1)

可以在C中进行一些类型推断。看一下这个工具:http://cuda.dcc.ufmg.br/psyche-c。您可以在那里键入程序的一部分,它将重建缺少的类型声明。例如,如果我们用Norman程序的变体喂它:

int length(T p) {
  if (p == NULL) return 0;
  else return 1 + length(p->next);
}

然后psyche-c找到这些声明:

#include <stdint.h>
#define NULL ((void*)0)
typedef int bool;
bool false = 0;
bool true = 1;
typedef  struct T {struct T* next;}* T;

例如,这种类型的重建对于代码完成很有用。

答案 4 :(得分:0)

C有一套关于类型提升和转换的复杂规则,即使人们真正看到他们正在处理的类型,他们也会感到困惑。我怀疑即使C有类型推断,也有必要声明类型以防止每三个函数出现荒谬的错误。

答案 5 :(得分:0)

我认为无法使用推断类型的某些情况:

  • 指针需要明确的类型
  • 数组需要明确的类型
  • 函数参数需要一个类型

我认为它可能适用于少数情况,主要是简单的局部变量。

即使像计算校验和这样简单的事情也需要明确的类型

crc8 = 0x00; /* 8 bits; cf uint8_t crc8 = 0; */
crc32 = 0x00000000; /* 32 bits; cf uint32_t crc32 = 0; */

可以这样做,但用途有限。