从理论上讲,void 是其他语言中称为unit 或top 的类型。它的逻辑等价物是True。任何值都可以合法地转换为void(每种类型都是void 的子类型)。将其视为“宇宙”集合; 所有世界上的值没有共同的操作,所以没有对void类型的值的有效操作。换一种说法,告诉你某物属于宇宙集不会给你任何信息——你已经知道了。所以以下是合理的:
(void)5;
(void)foo(17); // whatever foo(17) does
但下面的赋值不是:
void raise();
void f(int y) {
int x = y!=0 ? 100/y : raise(); // raise() returns void, so what should x be?
cout << x << endl;
}
另一方面,
[[noreturn]] 有时被称为 empty、Nothing、Bottom 或 Bot,并且在逻辑上等同于 False。它根本没有值,并且这种类型的表达式可以转换为任何类型(即它的子类型)。这是空集。请注意,如果有人告诉您“表达式 foo() 的值属于空集”,则它高度提供了丰富的信息 - 它告诉您该表达式永远不会完成其正常执行;它会中止、抛出或挂起。它与void 完全相反。
所以下面的没有意义(伪C++,因为noreturn不是一流的C++类型)
void foo();
(noreturn)5; // obviously a lie; the expression 5 does "return"
(noreturn)foo(); // foo() returns void, and therefore returns
但是下面的赋值是完全合法的,因为throw 被编译器理解为不返回:
void f(int y) {
int x = y!=0 ? 100/y : throw exception();
cout << x << endl;
}
在理想情况下,您可以使用noreturn 作为上述函数raise() 的返回值:
noreturn raise() { throw exception(); }
...
int x = y!=0 ? 100/y : raise();
遗憾的是,C++ 不允许这样做,可能是出于实际原因。相反,它使您能够使用[[ noreturn ]] 属性,这有助于指导编译器优化和警告。