Тип теоретически говоря, void
это то , что называется на других языках unit
или top
. Его логический эквивалент - Истина . Любое значение может быть законно приведено к 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 ]]
атрибут, который помогает направлять оптимизацию компилятора и предупреждения.