Noreturn是函数签名的一部分吗?可以检测到吗?

时间:2018-07-10 15:11:48

标签: c++ c++11 generic-programming noreturn

[dcl.attr.noreturn]可用于标记函数不返回。

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

[[noreturn]]是否属于功能的身份/签名?可以在编译时检测到某个函数为noreturn吗?

例如,

static_assert(is_noreturn(f));

如果不是这样,我应该采用约定定义标签结构吗?

struct noreturn_{noreturn_()=delete;};
...
[[noreturn]] noreturn_ f(){throw "error";}

2 个答案:

答案 0 :(得分:8)

“签名”具有非常精确的定义。好吧,several,取决于您所谈论的内容:

  
      
  • ⟨函数⟩名称,参数类型列表([dcl.fct]),名称空间(如果有)和结尾的需要子句([dcl.decl])(如果有)< / li>   
  • “功能模板”的名称,参数类型列表([dcl.fct]),封闭的名称空间(如果有),返回类型, template-head 和结尾的 requires-clause < / em>([[dcl.decl])(如果有)
  •   
  • “功能模板专业化”是其专业化的模板及其模板参数的签名(无论是明确指定还是推论)
  •   
  • “类成员函数”的名称,参数类型列表([dcl.fct]),该函数为其成员的类, cv限定符(如果有), ref-限定符(如果有),后跟需要子句([dcl.decl])(如果有)
  •   
  • “类成员函数模板”的名称,参数类型列表([dcl.fct]),其类   该函数是成员, cv限定词(如果有), ref-限定词(如果有),返回   类型(如果有),模板头和结尾的需要子句([dcl.decl])(如果有)
  •   
  • “类成员函数模板专门化”为其专门化的成员函数模板的签名及其   模板参数(无论是明确指定还是推导)
  •   

其中没有属性。

[[noreturn]]也不属于该类型。它属于功能,而不是功能的类型。


  

在编译时是否可以检测到函数没有返回?

不。委员会为属性建立的规则是“在忽略特定属性的所有实例的情况下编译有效程序,必须正确解释原始程序”。如果您可以通过编程方式检测属性的存在,则该规则将不成立。


  

如果不是这样,我是否应该采用约定并[d]定义标记结构?

目前还不清楚这种标签的用途。

答案 1 :(得分:5)

如果它是类型的一部分,则正确的类型检查编译器将不接受 例如:

[[noreturn]] int f(void);
int (*fp)(void) = f;

上面的编译没有错误。 [[noreturn]]不是该类型的一部分。 (顺便说一下,{11}在C11中也不是,它在语法上与_Noreturn属于同一类别。)

关于检测它,我在C ++ 11标准草案中没有找到任何机制。诸如您所提议的约定之类的约定可以允许您检测到它,但是您仅限于遵循该约定的函数。