【问题标题】:Can I use [[noreturn]] on non-void returning functions?我可以在非 void 返回函数上使用 [[noreturn]] 吗?
【发布时间】:2016-07-27 21:03:26
【问题描述】:

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

以下定义是否明确?

[[ noreturn ]] int function();

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

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

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

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

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

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

【问题讨论】:

  • 你可能会遇到迂腐的麻烦,允许实现假设无限循环结束。 (link)
  • @chris 我也希望用 [[maybe_unused]] 标记返回值。
  • 来自您发布的链接:如果具有此属性的函数实际返回,则行为未定义。

标签: c++ c++11 return undefined-behavior noreturn


【解决方案1】:

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

attribute-token noreturn 指定函数不返回。它最多出现一次 每个 attribute-list 并且不存在 attribute-argument-clause。该属性可以应用于 declarator-id 在函数声明中。函数的第一个声明应指定noreturn 如果该函数的任何声明指定了noreturn 属性,则属性。如果一个函数被声明为 一个翻译单元中的noreturn 属性,并且在没有noreturn 的情况下声明了相同的函数 另一个翻译单元中的属性,程序格式错误;无需诊断。

如果调用函数 f,而 f 之前已使用 noreturn 属性声明,并且 f 最终返回, 行为未定义。

没有提到返回类型。唯一重要的是函数不返回。如果函数返回(voidintvector&lt;vector&lt;double&gt;&gt;),则行为未定义。如果函数不返回,则返回类型无关紧要。

【讨论】:

    【解决方案2】:

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

    如果函数 f 被调用,而 f 之前用 noreturn 属性和 f 最终返回,行为是 undefined. [注意:函数可能会通过抛出一个 例外。 —尾注] [注:鼓励实现 如果标记为 [[noreturn]] 的函数可能返回,则发出警告。 - 结尾 注意]

    由于您的函数永远不会到达return 0;,因此没有 UB。

    【讨论】:

    • 这如何回答这个问题? OP 知道它不应该返回,他在询问它的类型。
    • 标准引用如何阐明它 ub? OP 的函数最终不会返回。
    • @Barry 不返回0
    • @101010 它永远不会到达那条线。
    【解决方案3】:

    我找到了一个非 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&lt;T&gt;("") 的结果类型为T 而不是[[noreturn]] T)。

    【讨论】:

      猜你喜欢
      • 2011-01-15
      • 1970-01-01
      • 2013-04-04
      • 2016-08-28
      • 1970-01-01
      • 2013-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多