Pregunta ¿Sería posible agregar inferencia tipo al lenguaje C?


Digamos que creamos una reimplementación de C, con la única diferencia de que tipos son inferidos Las clases de almacenamiento y los modificadores aún tendrían que ser dado (const, estático, restringir, etc.), y restrinjamos nuestra atención al single archiva programas C por el momento. ¿Podría hacerse? ¿Cuáles son los principales impedimentos?

Algunas reflexiones sobre lo que podría causar problemas con la inferencia de tipos

  • las estructuras con el mismo nombre de campo necesitarían ser desambiguadas manualmente
  • lo mismo para las uniones con los mismos nombres de campo
  • los moldes probablemente necesitarían una anotación "de", algo así como

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

Estos problemas requerirían un poco de anotación del usuario, pero no deberían ser demasiado gravoso, ¿hay algún problema mortal que haga volar esta idea fuera del agua?

Editar: para aclarar, no estoy hablando de agregar genéricos o polimorfismo paramétrico, solo escriba inferencia para los tipos de C existentes.

Edición 2014: cualquier persona interesada en este concepto puede querer investigar Moho


13
2018-06-28 22:26


origen


Respuestas:


C promueve algunos tipos de forma automática, lo que complica las cosas. Pero para que sea viable, debe tener un par de diferencias adicionales de C tal como existen: en este momento, el estándar aún admite hasta cierto punto los programas K & R C heredados, y eso requiere que los tipos no especificados se manejen de maneras particulares. (Ver, por ejemplo, las reglas para los parámetros de función en ausencia de prototipos. También solía ser posible especificar funciones y variables con no tipo, y serían predeterminados para (int). (¿Qué ocurre con las variables? Clase de almacenamiento únicamente. static foo;)) Todo este manejo de tipos heredados debería eliminarse antes de que se pueda agregar un nuevo mecanismo de tipos implícitos.


5
2018-06-28 22:36



GCC 5.1 admite:


9
2017-07-29 19:15



Inferir tipos de funciones polimórficas requeriría extensiones dramáticas para el sistema de tipo C. Ejemplo

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

Este código tiene que funcionar en cualquier puntero a una estructura (o una unión) con un next campo. Puede ver el polimorfismo de fila, pero al menos, su nuevo sistema de tipo va a tener que ser mucho más expresivo que el sistema de tipo C.

Otro problema apremiante es el sobrecargado + operación. ¿A qué tipo está predeterminado? ¿Desea que esté sobrecargado en cualquier tipo numérico, como Haskell o C ++? Si es así, más extensiones grandes para el sistema de tipo.

La lección más grande es no hagas esto. Los méritos de C (como lenguaje, aparte de las muchas API finas disponibles en C) son

  • Usted tiene control total sobre la representación de sus datos.
  • Cualquier persona que inspeccione el código fuente puede predecir fácilmente los costos de tiempo y espacio.

Esta agenda no es realmente compatible con el polimorfismo, y el polimorfismo es un beneficio principal de la inferencia de tipo. Si la inferencia de tipo es lo que desea, elija uno de los muchos lenguajes finos (F #, Haskell, ML) que lo soportan de forma nativa.


4
2018-06-29 00:45



Es posible hacer algunos escriba inferencia en C. Eche un vistazo a esta herramienta: http://cuda.dcc.ufmg.br/psyche-c. Puede escribir parte de un programa allí, y reconstruirá las declaraciones de tipos faltantes. Por ejemplo, si lo alimentamos con una variación del programa de Norman:

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

Entonces psyche-c encuentra estas declaraciones:

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

Este tipo de reconstrucción de tipo es útil para completar el código, por ejemplo.


1
2017-10-31 11:15



C tiene un conjunto complicado de reglas con respecto a la promoción y conversión de tipos que las personas encuentran confusas, incluso cuando realmente pueden ver los tipos con los que están lidiando. Sospecho que incluso si C tuviera una inferencia de tipo, sería necesario declarar los tipos para evitar errores ridículos cada tercera función.


0
2018-06-28 22:33



Algunas situaciones en las que, creo, los tipos inferidos no se pueden usar:

  • los punteros necesitan un tipo definido
  • matrices necesitan un tipo definido
  • los parámetros de función necesitan un tipo

Creo que podría funcionar en algunos casos, principalmente variables locales simples.

Incluso algo tan simple como calcular una suma de comprobación necesita un tipo definido

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

Podría hacerse, para un uso limitado.


0
2018-06-28 23:43