为什么 g++ 不发出这个与构造函数相关的 noexcept 启用"-fpic"的警告?

Why doesn't g++ emit this constructor-related noexcept warning with `-fpic` enabled?

本文关键字:noexcept 启用 -fpic 警告 构造函数 g++ 为什么      更新时间:2023-10-16

我有下一个代码:

#include <exception>
#include <cstdlib>
void g() { throw 1; }
void (*p)() = g;
template <class T>
void f(T) noexcept (noexcept (T())) // warning 1
{
p();
}
struct A { A() { } };           // warning 2
int main()
{
try { f(A()); } catch (int) { }
return 1;
}

下一个选项:
-fno-pic -fmessage-length=0 -std=c++0x -Wnoexcept
g++抛出下一个警告:

noexcept03.C:16:6: warning: noexcept-expression evaluates to 'false' because of a call to 'A::A()' [-Wnoexcept]
noexcept03.C:21:12: warning: but 'A::A()' does not throw; perhaps it should be declared 'noexcept' [-Wnoexcept]

但是,为什么当我使用-fpic而不是-fno-pic时,g++不会发出任何警告?

编辑:
GCC版本-4.7.2

-fpic的情况下不会发出警告,因为编译器假设构造函数A::A()可以抛出。

在编译PIC代码时,GCC假设每个全局名称都可以被其他模块的符号覆盖。因此,在没有显式noexcept声明的情况下,GCC必须保守地假设这样的函数可以抛出异常,即使它可以静态地证明它现在看到的版本不能。

如需参考,请参阅此处的错误和补丁http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29323#c7(代码从那以后有点变化,但它是这样开始的)

以上适用的示例:

/* inline */ int f() { return 0; }
int g() noexcept (noexcept(f())) { return f() + 1; }

所以,这就是没有警告的直接原因。以下是我对它的看法。

然而,C++11说:

7.1.2函数说明符[dcl.fct.spec]

4应在它是odr使用的,并且在每个案例(3.2)。

即,对于内联函数,如果一个函数被确定为不抛出,GCC可以假设这样一个函数的每个潜在覆盖也不能抛出。

从这个意义上说,GCC对内联函数过于保守,无论是在原始测试用例中,还是在上面未注释inline关键字的示例中,即使使用了-fpic/-fPIC,GCC也应该发出警告。