为什么C的void类型不同于Empty / Bottom类型?


28

维基百科以及我发现的其他来源都将C的void类型列为单位类型,而不是空类型。我觉得这很混乱,因为在我看来,它void更适合于空/底类型的定义。

  • void据我所知,没有价值观存在。
  • 返回类型为void的函数指定该函数不返回任何内容,因此只能执行某些副作用。
  • 类型的指针void*是所有其他指针类型的子类型。同样,void*在C中进行来回转换是隐式的。

我不确定最后一点是否可以作为void空类型的参数,void*或多或少是与无关的特例void

另一方面,void它本身不是所有其他类型的子类型,据我所知,这是将类型作为底部类型的要求。


10
“不返回任何东西”实际上是指“不返回任何感兴趣的东西”,而输出为空的函数根本不返回(即崩溃或无限循环)。
特里

2
作为返回类型,void是单位类型。
user253751's

Answers:


38

在C中,void用于多个不相关的事物。根据其用途,其含义可能是单元类型,空类型或其他类型。

当单独void使用(相对于void*指向void的指针)时,它是一个单元类型,即具有单个值的类型。void据说返回的函数“什么也不返回”,但这实际上意味着它们不返回任何信息。它们返回位信息,这意味着它们返回的类型值包含2 0 = 1个不同的值,即单位类型。020=1

这不是空类型:返回空类型的函数无法返回值,因为没有该类型的值。返回类型为空的函数只能永久循环,或者中止程序,或者引发异常(longjmp)(或者以其他方式不返回,例如,通过使用超出标准C的功能将控制权转移到另一个线程或进程)。为了使事情变得混乱,在C中常规使用void代替空类型(C没有空类型)。

void0voidvoidreturnvoidvoid

在允许任何可能的类型的意义上,C没有底部类型。甚至不完整的类型也会指定其值的一般性质,例如,指针,结构或联合或函数。但是void*是指向任何非函数类型的指针:它是对象指针类型的代数中的最小元素,即它是底部对象指针类型。与T*where T是某种非空类型的一般情况不同,void*不是类型为value的指针的类型void,而是类型为unspecified类型的值的指针的类型。


在C ++和C89中可以返回void。stackoverflow.com/questions/35987493/…–
BartekChom

2
第四段在形式上是错误的。在C中,的存储量void是不确定的,而不是零。这不是void不允许使用类型对象的原因。正式的原因是这void是一个不完整的类型,并且对象不能具有不完整的类型。
MSalters

4
@MSalters不,我写的内容在形式上是正确的。“因为”是指语言设计的动机,而不是语言规范内的逻辑推论。该void类型需要 0位存储空间。这就是为什么C的设计人员决定void采用不完整的类型的原因,而不是将其定义为占用0字节的存储空间(这将对语言设计产生很大影响)或占用1字节的存储空间(这将浪费空间)。 。
吉尔斯(Gilles)“所以

1
@吉尔斯:对不起,但这也没有道理。如果允许,则每个void类型的对象使用的空间为1个字节,并且您显然不需要很多void类型的对象。更不用说这些对象可以别名所有其他对象,因此实际使用情况无论如何都为零。
MSalters

4
@CodesInChaos:好吧,C ++实际上允许使用空结构,即struct E { };。当用作基类时,它的大小可以为零。(实际上没有C / C ++之类的东西,两种语言都有自己的选择,它们在这些方面可能有所不同。C显然没有空的基类,因为它首先没有OO)
MSalters

11

“空类型”这个名称可能令人困惑。就像您自己说的那样,这意味着类型不包含任何值。“空”不是指类型的任何单个值,而是指作为一个整体的类型,被视为一组可能的值。因此,这并不是说“函数void返回不返回任何信息”,而是“不存在类型的值”。

这意味着,其结果类型是一个函数可以永不终止。如果确实终止,则必须返回的值,但是,这样的值不存在。

这也意味着,甚至不可能讨论一个空类型的值将包含多少信息,因为没有这样的值。(或者,如果您愿意的话,像“任何空类型的值都恰好包含35093658位信息”这样的荒谬说法都是虚假的。)将值视为包含无限量的信息是有用的(尽管不是很正确)。

带有“返回类型”的C函数void显然可以返回,但不会在返回值中提供任何信息。好吧,这正是单元类型的特征:它的值不包含任何信息,因为只有一个这样的值(因此,即使您不必费心调用该函数,也可以始终说出返回值是什么)。

引用Conor McBride(音译为C):

void表示“无聊”。这意味着包含一件事的无聊类型,也很无聊。通过将无聊类型的一个元素与另一个元素进行比较,不会获得任何有趣的结果,因为没有任何注意力可以让您了解无聊类型的元素。

它与空类型[...]有很大不同。空类型非常令人兴奋,因为如果有人给了您属于它的价值,您就会知道自己已经死了,在天堂,而您想要的任何东西都是您的。


有趣; 如果the的定义是返回类型为⊥的函数永远不会终止,则C具有这种类型。我们称其为volatile void。
约书亚

有趣的是,我不知道。不过,我似乎实际上并不符合标准
左右约
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.