¿Está fuertemente tipado C?

Para citar Wikipedia :

Dos lenguajes de uso común que admiten muchos tipos de conversión implícita son C y C ++, y en ocasiones se afirma que se trata de lenguajes débilmente tipados. Sin embargo, otros argumentan que estos lenguajes colocan restricciones suficientes sobre cómo se pueden mezclar operandos de diferentes tipos, que los dos deben considerarse como lenguajes fuertemente tipados.

¿Hay una respuesta más definitiva?

“Fuertemente tipado” y “débilmente tipado” son términos que no tienen un significado técnico ampliamente aceptado. Los términos que sí tienen un significado bien definido son

  • Tipeado dinámicamente significa que los tipos se adjuntan a valores en tiempo de ejecución, y un bash de mezclar valores de diferentes tipos puede causar un “error de tipo de tiempo de ejecución”. Por ejemplo, si en Scheme intenta agregar uno a verdadero escribiendo (+ 1 #t) se producirá un error. Encuentra el error solo si intenta ejecutar el código ofensivo.

  • Estáticamente tipeado significa que los tipos se verifican en tiempo de comstackción, y un progtwig que no tiene un tipo estático es rechazado por el comstackdor. Por ejemplo, si en ML intentas agregar uno a verdadero escribiendo 1 + true , el progtwig será rechazado con un mensaje de error (probablemente críptico). Siempre obtiene el error incluso si el código nunca se puede ejecutar.

Diferentes personas prefieren diferentes sistemas de acuerdo, en parte, a cuánto valoran la flexibilidad y cuánto les preocupan los errores de tiempo de ejecución.

Algunas veces, “fuertemente tipado” se usa de manera general para significar “estáticamente estátizado”, y “tipado débilmente” se usa incorrectamente para indicar “tipeado dinámicamente”. Un mejor uso para el término “fuertemente tipado” es que “no se puede evitar o subvertir el sistema de tipo”, mientras que “escribir débilmente” significa “hay lagunas en el sistema de tipo”. Perversamente, la mayoría de los lenguajes con sistemas de tipo estático tienen escapatorias, mientras que muchos idiomas con sistemas de tipo dynamic no tienen escapatorias.

Ninguno de estos términos está conectado de ninguna manera con el número de conversiones implícitas disponibles en un idioma.

Si desea hablar con precisión sobre los lenguajes de progtwigción, es mejor evitar los términos “fuertemente tipado” y “débilmente tipado”. Diría que C es un lenguaje estático pero tiene muchas lagunas. Una de las lagunas es que puede convertir libremente cualquier tipo de puntero a cualquier otro tipo de puntero. También puede crear una brecha entre dos tipos de su elección al declarar una unión C que tiene dos miembros, uno para cada uno de los tipos en cuestión.

Escribí más sobre la tipificación estática y dinámica en por qué-interpreted-langs-are-mostly-ducktyped-while-compiled-have-strong-typing .

Es difícil clasificar todos los idiomas en tipeados “débilmente” o “fuertemente”, es más un continuo. Pero, en comparación con otros lenguajes, C está bastante fuertemente tipado. Cada objeto tiene un tipo de tiempo de comstackción, y el comstackdor le avisará (en voz alta) si está haciendo algo con un objeto que su tipo no le permite hacer. Por ejemplo, no puede llamar a funciones con los tipos de parámetros incorrectos, acceder a los miembros de struct / union que no existen, etc.

Pero hay algunas debilidades. Una de las principales debilidades es el tipo de emisiones: básicamente dicen que vas a estar usando el tipo de objetos y el comstackdor debe estar en silencio (cuando puede). void* es también otra debilidad: es un puntero genérico a un tipo desconocido, y cuando los usas, tienes que tener especial cuidado de estar haciendo lo correcto. El comstackdor no puede verificar estáticamente la mayoría de los usos de void* . void* también se puede convertir en un puntero a cualquier tipo sin un molde (solo en C, no en C ++), que es otra debilidad.

C se considera de tipo débil, porque puede convertir cualquier tipo a cualquier otro tipo a través de un molde, sin un error de comstackción. Puedes leer más sobre el tema aquí .

La literatura no es clara sobre esto. Creo que fuertemente tipado no es sí / no, hay diferentes grados de tipeo fuerte.

Un lenguaje de progtwigción tiene una especificación de cómo ejecuta progtwigs. A veces no está claro cómo ejecutar con ciertos progtwigs. Por ejemplo, progtwigs que intentan restar una cadena de un número. O progtwigs que se dividen por cero. Hay varias formas de lidiar con estas condiciones. Algunos idiomas tienen reglas para manejar estos errores (por ejemplo, lanzan una excepción). Otros idiomas simplemente no tienen reglas para lidiar con estas situaciones. Esos lenguajes generalmente tienen sistemas de tipo para evitar la comstackción de progtwigs que conducen a un comportamiento no especificado. Y también existen lenguajes que tienen un comportamiento no especificado y no tienen un sistema de tipos para evitar estos errores en tiempo de comstackción (si escribes un progtwig que golpea un comportamiento no especificado podría lanzar los misiles).

Asi que:

Los lenguajes que especifican qué sucede en el tiempo de ejecución en cada caso (como agregar un número a una cadena) se llaman de forma dinámica. Los lenguajes que impiden la ejecución de progtwigs con errores en tiempo de comstackción están tipados estáticamente. Los lenguajes que no especifican lo que sucede y que tampoco tienen un sistema de tipo para evitar errores se llaman de tipo débil.

Entonces, ¿está Java estáticamente tipado? Sí, porque su sistema de tipos no permite restar una cadena de un número. No, porque te permite dividir por cero. Podría evitar la división por cero en tiempo de comstackción con un sistema de tipos. Por ejemplo, al crear un tipo de número que no puede ser cero (por ejemplo, NonZeroInt), y solo permite dividir por números que tienen este tipo.

Entonces, ¿C está fuertemente tipado o débilmente tipado? C está fuertemente tipado porque el sistema de tipo no permite algunos tipos de errores. Pero está tipeado débilmente en otros casos cuando no está definido lo que sucede (y el sistema de tipos no lo protege).

C es más fuertemente tipeado que Javascript y menos tipado que Ada.

Yo diría que cae más en el lado fuertemente tipado del continuo. pero alguien más puede estar en desacuerdo (incluso si están equivocados).

¿Cómo es eso definitivo?

C se considera tipado estáticamente (no puede tener un cambio de variable de int a float). Una vez que se declara una variable, se bloquea de esa manera.

Pero se considera tipeado débilmente porque los tipos pueden voltearse.

¿Qué es 0? ‘\ 0’, FALSE, 0.0, etc.

en muchos idiomas no se puede decir IF (variable) porque las condiciones solo tomarán los valores booleanos de las expresiones booleanas. Estos son más fuertemente tipados. Lo mismo aplica para ir entre caracteres y números enteros.

Básicamente c tiene dos tipos principales de datos simples, enteros y números de punto flotante (aunque varias precisiones). Todo lo demás booleanos, enumeraciones (no simples pero que encajan), etc. se implementan como uno de esos. Incluso los personajes son básicamente enteros.

Compare con otros lenguajes donde hay tipos de cadenas, tipos enum que solo se pueden asignar a los valores definidos, tipos booleanos donde solo se pueden usar expresiones que generan booleanos o verdadero / falso.

Pero puede argumentar que en comparación con Perl C está fuertemente tipado. Entonces, es uno de esos argumentos famosos (vi vs emacs, linux vs windows, etc.). C # es más tipeado que C. Básicamente puedes discutir de cualquier manera. Y sus respuestas probablemente irán en ambos sentidos 🙂 También algunos libros de texto / páginas web dirán que C está débilmente tipado, y algunos dirán que C está fuertemente tipado. Si vas a wikipedia, la entrada C dice “tipeo parcialmente débil”. Yo diría que comparado con Python C está débilmente tipado. Entonces Python / C #, C, Perl en el continuo.

Muchas buenas respuestas aquí. Quiero mencionar un punto importante de Real World Haskell :

Es útil tener en cuenta que muchas comunidades lingüísticas tienen sus propias definiciones de un “tipo fuerte”. Sin embargo, hablaremos brevemente y en términos generales sobre la noción de fortaleza en los sistemas de tipos.

(recorte)

Los fuegos artificiales alrededor de los sistemas de tipo tienen sus raíces en el inglés común, donde las personas asocian nociones de valor a las palabras “débil” y “fuerte”: generalmente pensamos que la fuerza es mejor que la debilidad. Muchos otros progtwigdores hablan inglés llano que la jerga académica, y muy a menudo los académicos realmente están lanzando tachuelas en cualquier sistema de tipos que no les convenga. El resultado es a menudo ese popular pasatiempo en Internet, una guerra de llama.

Por lo tanto, mira las respuestas sobre C y C ++, pero recuerda que “fuerte” y “débil” no se asignan a “bueno” y “malo”.

En mi opinión, C / C ++ está fuertemente tipado. El tipo de pirateo que permite la conversión de tipos (void *) existe debido a la cercanía de C con la máquina. En otras palabras, puede llamar comandos de ensamblador desde Pascal y manipular punteros, y Pascal todavía se considera un lenguaje fuertemente tipado. Puede invocar ensambladores y ejecutables C desde Java a través de JNI, pero no hace que Java sea débilmente tipeado.

C solo tiene ensamblador “incrustado” en él con punteros sin procesar y demás.

El término fuertemente tipificado no tiene una definición acordada. Por lo tanto, a menos que defina lo que quiere decir con “fuertemente tipado”, es imposible responder a su pregunta.

En mi experiencia, los términos “fuertemente tipado” y “débilmente tipado” son utilizados exclusivamente por los trolls, porque su falta de definiciones permite a los trols redefinirlos en medio de los argumentos para adaptarlos a su agenda. Aparte de iniciar flamewars, estos términos son bastante inútiles.

También es posible que desee echar un vistazo a ¿Cuáles son los aspectos clave de un lenguaje fuertemente tipado? aquí en StackOverflow.

Según Dennis Ritchie ( creador de C ) y Brian Kernighan, C no es un lenguaje fuertemente tipado. Las siguientes líneas son del libro The C language language page 3 paragraph 5

C no es un lenguaje fuertemente tipado, pero a medida que evolucionó, su verificación de tipos se ha fortalecido.

Existe un continuo con múltiples avenidas paralelas entre “débilmente tipado” y “fuertemente tipado”, dos términos que ni siquiera están bien definidos.

C está tipado estáticamente , ya que el comstackdor sabe cuál es el tipo declarado de cada variable local y miembro de la estructura.

Los lenguajes de tipeo dynamic aún pueden estar fuertemente tipados, si cada objeto tiene un tipo específico pero no hay forma de que el comstackdor sepa ese tipo.

c está débilmente tipado, b es sin tipo.

¿Cuál es el motivo de tu consulta? La razón por la que pregunto es que esta es una pequeña diferencia y su uso particular de “fuertemente tipado” podría necesitar más o menos aclaración. Definitivamente diría que Java y otros lenguajes tienen restricciones más estrictas en la conversación de tipo implícito.

Es difícil dar una respuesta concreta cuando no hay una definición concreta de “fuertemente tipificado”. Yo diría que C está fuertemente tipado en que cada variable y cada expresión tiene un tipo pero débilmente tipado que le permite cambiar tipos usando moldes y reinterpretar la representación de un tipo como otro.

Diría que C está tan fuertemente tipado como lo dicta su comstackdor / plataforma. Por ejemplo, si está construyendo sobre una plataforma estricta, es probable que la desreferenciación de un puntero tipo punteado se rompa:

 void m_free(void **p) { if (*p != NULL) { free(*p); *p = NULL; } } .... char *str = strdup("foo"); m_free((void **) &foo); 

Ahora, si le dices al comstackdor que saltee el aliasing estricto, sería un problema, pero no muy portátil. Entonces, en ese sentido, presionar los límites del lenguaje es posible, pero probablemente no sea la mejor idea. Eso va un paso más allá del casting típico, es decir, lanzar int por mucho tiempo y realmente muestra uno de los posibles escollos del vacío.

Entonces, yo diría que C está estrictamente tipado, pero sus diversos comstackdores presumen que el progtwigdor sabe mejor y permite cierta flexibilidad. Esto realmente depende del comstackdor, algunos no se darían cuenta de ese potencial ¡Uy! Entonces, en ese sentido, el comstackdor de elección realmente juega un papel al responder la pregunta. Lo que es correcto a menudo difiere de lo que su comstackdor le permitirá salirse con la suya.

No fuertemente tipado.

Considere lo que el siguiente prototipo de función le dice sobre los tipos de datos de los argumentos:

 void func (int n, char ch, ...); 

Nada. Así que sugiero que la tipificación fuerte no se aplica aquí.

Yo diría que está fuertemente tipificado ya que cada expresión tiene un tipo que no es una función de su valor; ei se puede conocer antes del tiempo de ejecución.

OTOH No estoy seguro de que sea la descripción correcta de fuertemente tipado. La única afirmación más fuerte que puedo ver sobre el motivo de un lenguaje sería la seguridad de que no se puede subvertir el sistema de tipos en tiempo de ejecución mediante la reinterpretación de conversiones, uniones, llamadas a otros idiomas, punteros, ensamblador, etc. Idiomas como este existen pero están tan paralizados que parecen no ser de mucho interés para los progtwigdores fuera de la alta seguridad y la academia. Como señaló alguien, para realmente hacerlo bien, empiezas a necesitar tener tipos como nonZeroInt y nonZeroInt . Yuck.