¿Por qué el tipo de vacío de C no es análogo al tipo vacío / inferior?


28

Wikipedia, así como otras fuentes que he encontrado, enumeran el voidtipo de C como un tipo de unidad en lugar de un tipo vacío. Esto me parece confuso, ya que me parece que se voidajusta mejor a la definición de un tipo vacío / inferior.

  • No habito valores void, por lo que puedo decir.
  • Una función con un tipo de retorno de vacío especifica que la función no devuelve nada y, por lo tanto, solo puede realizar algún efecto secundario.
  • Un puntero de tipo void*es un subtipo de todos los demás tipos de puntero. Además, las conversiones hacia y desde void*C son implícitas.

No estoy seguro de si el último punto tiene algún mérito como argumento para voidser un tipo vacío, ya que void*es más o menos un caso especial con poca relación void.

Por otro lado, en voidsí mismo no es un subtipo de todos los demás tipos, lo que, por lo que puedo decir, es un requisito para que un tipo sea de tipo inferior.


10
Por "no devuelve nada" quiere decir "no devuelve nada de interés", mientras que una función con salida vacía no regresa en absoluto (es decir, se bloquea o se repite infinitamente).
Turion

2
Como tipo de retorno, void es un tipo de unidad.
user253751

Respuestas:


38

En C, voidse usa para múltiples cosas no relacionadas. Dependiendo de para qué se use, su significado puede ser un tipo de unidad, un tipo vacío u otra cosa.

voidvoid*void020=1

Este no es un tipo vacío: una función que devuelve un tipo vacío no puede devolver un valor, ya que no hay ningún valor de ese tipo. Una función cuyo tipo de retorno está vacío solo puede recorrer en bucle para siempre, o abortar el programa, o generar una excepción ( longjmp) (u organizar de otro modo para no regresar, por ejemplo, transfiriendo el control a otro hilo o proceso usando una funcionalidad más allá del estándar C). Para mantener las cosas confusas, es convencional en C usar voiden lugar de un tipo vacío (C no tiene un tipo vacío).

void0voidvoidreturnvoidvoid

C no tiene un tipo de fondo en el sentido de permitir cualquier tipo posible. Incluso los tipos incompletos especifican la naturaleza general de sus valores, por ejemplo, punteros o estructuras o uniones o funciones. Pero void*es un puntero a cualquier tipo sin función: es el elemento mínimo del álgebra de los tipos de puntero de objeto, es decir, es el tipo de puntero de objeto inferior. A diferencia del caso general de T*dónde Thay algún tipo no nulo, void*no es el tipo de punteros a un valor de tipo void, sino el tipo de punteros a un valor de tipo no especificado.


Uno puede devolver nulo en C ++ y C89. stackoverflow.com/questions/35987493/…
BartekChom

2
El cuarto párrafo está formalmente equivocado. En C, la cantidad de almacenamiento para voides indefinida, no cero. Esta no es la razón por la cual los objetos de tipo voidno están permitidos. La razón formal es que voides un tipo incompleto y los objetos no pueden tener un tipo incompleto.
MSalters

44
@MSalters No, lo que escribí es formalmente correcto. "Porque" se refiere a la motivación para el diseño del lenguaje, no a las inferencias lógicas dentro de la especificación del lenguaje. El voidtipo requiere 0 bits de almacenamiento. Esta es la razón por la cual los diseñadores de C decidieron hacer voidun tipo incompleto, en lugar de definirlo tomando 0 bytes de almacenamiento (lo que tendría un gran impacto en el diseño del lenguaje) o 1 byte de almacenamiento (lo que desperdiciaría espacio) .
Gilles 'SO- deja de ser malvado'

1
@Gilles: Lo siento, pero eso tampoco tiene sentido. Si se permite, el espacio utilizado sería de 1 byte por objeto de tipo vacío , y obviamente no necesita muchos objetos de voidtipo. Sin mencionar que estos objetos podrían alias a todos los demás objetos, por lo que el uso real sería cero de todos modos.
MSalters

44
@CodesInChaos: Bueno, C ++ en realidad permite estructuras vacías, es decir struct E { };. Cuando se usa como una clase base, puede ser de tamaño cero. (Realmente no existe tal cosa como C / C ++, los dos idiomas toman sus propias decisiones y pueden diferir en estas áreas. C obviamente no tiene clases base vacías, ya que no tiene OO en primer lugar)
MSalters

11

El nombre "tipo vacío" es quizás confuso. Lo que esto significa es, como usted mismo dice, el tipo no contiene valores . El "vacío" no se refiere a ningún valor individual del tipo, se refiere al tipo como un todo, considerado como un conjunto de valores posibles. Por lo tanto, esto no dice algo como "una función que voiddevuelve no devuelve información", sino "no existe ningún valor de tipo ".

Esto significa que una función cuyo tipo de resultado es nunca puede terminar. Si terminara, tendría que devolver un valor de , pero, bueno, ese valor no existe.

También significa que ni siquiera es posible discutir cuánta información contendría un valor de tipo vacío, porque no existe tal valor. (O, si lo desea, una afirmación sin sentido como "cualquier valor de tipo vacío contiene exactamente 35093658 bits de información" es completamente cierto). Es algo útil (aunque no realmente correcto) pensar que los valores contienen una cantidad infinita de información.

Mientras que una función C con "tipo de retorno" voidclaramente puede regresar, pero no le da ninguna información en su valor de retorno. Bueno, eso es precisamente lo que caracteriza un tipo de unidad: sus valores no contienen ninguna información, porque solo hay uno de esos valores (por lo tanto, siempre puede decir cuál será el valor de retorno, incluso sin molestarse en llamar a la función).

Para citar a Conor McBride (transcrito a C):

voidsignifica "aburrido". Significa el tipo aburrido que contiene una cosa, también aburrida. No hay nada interesante que ganar al comparar un elemento del tipo aburrido con otro, porque no hay nada que aprender sobre un elemento del tipo aburrido prestándole atención.

Es muy diferente del tipo vacío [...]. El tipo vacío es muy emocionante, porque si alguien alguna vez te da un valor que le pertenece, sabes que ya estás muerto y en el cielo y que todo lo que quieras es tuyo.


Interesante; si la definición de ⊥ es la función cuyo tipo de retorno es ⊥ nunca puede terminar, entonces C tiene ese tipo. Lo llamamos vacío volátil.
Joshua

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.