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

问题描述 投票:0回答:6

比方说,我们创建了 C 的重新实现,唯一的区别是 类型是推断出来的。存储类和修饰符仍然需要 给定(const、static、restrict 等),让我们将注意力限制在单个 暂时归档 C 程序。能做到吗?主要有哪些 障碍?

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

  • 具有相同字段名称的结构需要手动消除歧义
  • 对于具有相同字段名称的联合也是如此
  • 强制转换可能需要“from”注释,例如

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

这些问题需要一些用户注释,但不应该太多 繁重的,是否有一些致命的问题让这个想法从水中消失?

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

编辑 2014:任何对这个概念感兴趣的人都可能想研究一下 Rust

c compiler-construction type-inference language-design
6个回答
13
投票

GCC 5.1 支持:


6
投票

C 自动提升某些类型,这使事情变得复杂。 但为了可行,您需要与 C 存在一些额外的差异:目前,该标准仍然在某种程度上支持旧版 K&R C 程序,并且这要求以特定方式处理未指定的类型。 (例如,参见没有原型的函数参数规则。过去也可以用 no 类型指定函数和变量,并且它们将默认为

(int)
。(变量如何?存储仅类。
static foo;
))在添加新的隐含类型机制之前,必须删除所有这些遗留类型处理。


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)之一。


1
投票

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


1
投票

可以在 C 中进行 some 类型推断。请查看此工具:http://cuda.dcc.ufmg.br/psyche-c。您可以在那里键入程序的一部分,它将重建丢失的类型声明。例如,如果我们向它提供诺曼程序的变体:

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;

这种类型重构对于代码完成等很有用。


0
投票

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

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

我认为它可以适用于几种情况,主要是简单的局部变量。

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

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

可以做到,但用途有限。

© www.soinside.com 2019 - 2024. All rights reserved.