处理gcc的noexcept-type警告

Bar*_*rry 32 c++ g++ noexcept c++17 gcc7

bug 80985开始考虑这个例子:

template <class Func>
void call(Func f)
{
    f();
}

void func() noexcept { }

int main()
{
    call(func);
}
Run Code Online (Sandbox Code Playgroud)

正如您所做的那样,在启用所有警告的情况下进行编译会产生:

$ g++ -std=c++14 -Wall foo.cxx 
foo.cxx:2:6: warning: mangled name for ‘void call(Func) [with Func = void (*)() noexcept]’ will change in C++17 because the exception specification is part of a function type [-Wnoexcept-type]
 void call(Func f)
      ^~~~
Run Code Online (Sandbox Code Playgroud)

我应该怎么做这个警告呢?修复是什么?

Ros*_*dge 20

关于警告信息,您可以做几件事.

禁用它-Wno-noexcept-type.在许多项目中,警告消息是无益的,因为结果对象不可能与另一个期望使用GCC的C++ 17名称修改的对象链接.如果您没有使用不同的-std=设置进行编译,并且您没有构建静态或共享库,其中违规功能是其公共接口的一部分,则可以安全地禁用警告消息.

编译所有代码-std=c++17.警告消息将消失,因为该函数将使用新的受损名称.

做功能static.由于该函数不能再使用另一个对象文件引用该函数,因此不会显示警告消息.函数定义必须包含在使用它的所有编译单元中,但对于模板函数,例如在这个例子中,这是常见的.这也不适用于成员函数static意味着别的东西.

调用函数模板时,请指定模板参数,显式提供不具有异常规范的兼容函数指针类型.例如call<void (*)()>(func).您也应该能够使用强制转换来执行此操作,但即使使用-std=c++17不更改修改,GCC 7.2.0仍会生成警告.

当函数不是模板时,不要使用noexcept函数类型中使用的任何函数指针类型.这和最后一点依赖于这样一个事实:只有非抛出函数指针类型才会导致命名修改更改,并且可以将非抛出函数指针分配(C++ 11)或隐式转换(C++ 17)到可能抛出函数指针.