我可以在非 void 返回函数上使用 [[noreturn]] 吗?

Can I use [[noreturn]] on non-void returning functions?

我以前从未见过 [[ noreturn ]] 用于非空 returning 函数。

下面的定义好吗?

[[ noreturn ]] int function();

int function(){
  while(true){/* impl */}
  return 0;
}

return 类型必须是 int 的原因是因为该函数是通过函数指针传递给另一个函数的。

所以假设来电者看起来像这样:

//call the non-returning function
int var = (*fptr)();

//use var some way (even though the function will never actually return)
std::cout << var;

这会表现出任何类型的未定义行为吗?

[[noreturn]] 的标准规范在 [dcl.attr.noreturn] 中。整个规范文本如下:

The attribute-token noreturn specifies that a function does not return. It shall appear at most once in each attribute-list and no attribute-argument-clause shall be present. The attribute may be applied to the declarator-id in a function declaration. The first declaration of a function shall specify the noreturn attribute if any declaration of that function specifies the noreturn attribute. If a function is declared with the noreturn attribute in one translation unit and the same function is declared without the noreturn attribute in another translation unit, the program is ill-formed; no diagnostic required.

If a function f is called where f was previously declared with the noreturn attribute and f eventually returns, the behavior is undefined.

return类型没有提及。唯一重要的是函数不是 return。如果函数 returns(无论是 voidintvector<vector<double>>),则行为未定义。如果函数不 return,return 类型无关紧要。

来自 C++ 标准 §7.6.8/p2 Noreturn 属性 [dcl.attr.noreturn](Emphasis Mine:

If a function f is called where f was previously declared with the noreturn attribute and f eventually returns, the behavior is undefined. [ Note: The function may terminate by throwing an exception. — end note ] [ Note: Implementations are encouraged to issue a warning if a function marked [[noreturn]] might return. — end note ]

因为你的函数永远不会达到 return 0; 所以没有 UB。

我发现了一个非 void [[noreturn]] 函数的实际例子。在一种情况下,当在 ?: 运算符中使用以提供 ?: 运算符的正确结果类型时:

template <class T> [[noreturn]] T fail(char const *s) noexcept { puts(s); exit(1); }
enum E { V1, V2 };
int f(E e) {
  return (e == V1) ? 1 : (e == V2) ? 2 : fail<E>("bad e");
}

注意:人们可能会觉得 ?: 运算符中的 [[noreturn]] 函数在计算 ?: 结果类型时可以忽略。但这是不可能的,因为 [[noreturn]] 不是表达式结果类型的一部分(fail<T>("") 的结果类型是 T 而不是 [[noreturn]] T)。