How can the operator()
of a lambda be declared as noreturn
?
Ideone accepts the following code:
#include
Clang is correct. An attribute can appertain to a function being declared, or to its type; the two are different. [[noreturn]]
must appertain to the function itself. The difference can be seen in
// [[noreturn]] appertains to the entity that's being declared
void f [[noreturn]] (); // §8.3 [dcl.meaning]/p1:
// The optional attribute-specifier-seq following a
// declarator-id appertains to the entity that is declared."
[[noreturn]] void h (); // §7 [dcl.dcl]/p2:
// "The attribute-specifier-seq in a simple-declaration
// appertains to each of the entities declared by
// the declarators of the init-declarator-list."
// ill-formed - [[noreturn]] appertains to the type (§8.3.5 [dcl.fct]/p1:
// "The optional attribute-specifier-seq appertains to the function type.")
void g () [[noreturn]] {}
Indeed if you compile this in g++ it tells you that
warning: attribute ignored [-Wattributes]
void g () [[noreturn]] {}
^
note: an attribute that appertains to a type-specifier is ignored
Note that it doesn't emit a warning that g()
actually does return.
Since an "attribute-specifier-seq in the lambda-declarator appertains to the type of the corresponding function call operator or operator template" (§5.1.2 [expr.prim.lambda]/p5) rather than to that operator/operator template itself, you can't use [[noreturn]]
there. More generally, the language provides no way for you to apply an attribute to the operator ()
of a lambda itself.