noreturn的意义是什么?

[dcl.attr.noreturn]提供了以下示例:

[[ noreturn ]] void f() { throw "error"; // OK } 

但是我不明白[[noreturn]]是什么意思,因为函数的返回types已经是void

那么, noreturn属性的重点是什么? 它应该如何使用?

noreturn属性应该用于不返回给调用者的函数。 这并不意味着void函数(返回给调用者 – 它们只是不返​​回值),而是函数完成后控制stream不会返callback用函数的函数(例如,退出应用程序的函数,永远循环或抛出exception,如你的例子)。

这可以被编译器用来做一些优化并产生更好的警告。 例如,如果f具有noreturn属性,那么在编写f(); g();时,编译器会提醒你g()是死代码f(); g(); f(); g(); 。 同样,编译器将不会在调用f()之后警告你缺less返回语句。

noreturn不会告诉编译器该函数不会返回任何值。 它告诉编译器控制stream不会返回给调用者 。 这允许编译器进行各种优化 – 它不需要保存和恢复任何在调用周围的易失状态,它可以死代码消除任何本来会跟随调用的代码,等等。

这意味着该function将无法完成。 在调用f()之后,控制stream将永远不会触发语句:

 void g() { f(); // unreachable: std::cout << "No! That's impossible" << std::endl; } 

这些信息可以被编译器/优化器以不同的方式使用。 编译器可以添加一个警告,说明上面的代码是不可访问的,它可以用不同的方式修改g()的实际代码,例如支持延续。

从理论上讲, void是其他语言unittop所谓的。 其逻辑等价物是True 。 任何值都可以合法地转换为void (每个types都是void的子types)。 把它看作“宇宙”的集合; 世界上所有的值都没有共同的操作,所以对voidtypes的值没有有效的操作。 换一种说法,告诉你属于宇宙集的东西不会给你任何信息 – 你已经知道了。 所以下面是声音:

 (void)5; (void)foo(); // whatever foo() 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]]有时被称为emptyNothingBottomBot并且是False的逻辑等价物。 它根本没有任何值,而且这种types的expression式可以被转换成任何types的(即子types)。 这是空的集合。 请注意,如果有人告诉你“expression式foo()的值属于空集”这是非常有用的信息 – 它告诉你,这个expression式永远不会完成它的正常执行; 它会中止,抛出或挂起。 这是void的完全相反。

所以下面没有意义(伪C ++,因为noreturn不是一stream的C ++types)

 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 ]]属性来帮助指导编译器优化和警告。