为什么g ++不会在启用`-fpic`的情况下发出与构造函数相关的noexcept警告?

Pep*_*lac 5 c++ optimization gcc g++ fpic

我有下一个代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

并有下一个选项:
-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]
Run Code Online (Sandbox Code Playgroud)

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

编辑:
GCC版本 - 4.7.2

chi*_*ill 5

在这种-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; }
Run Code Online (Sandbox Code Playgroud)

所以,这是"为什么"没有警告的直接原因.以下是我的想法.

但是,C++ 11说:

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

4内联函数应在每个使用过的翻译单元中定义,并且在每种情况下都应具有完全相同的定义(3.2).

即对于内联函数,如果确定函数不抛出,GCC可以假设这样一个函数的每个可能的覆盖都不能抛出.

从这个意义上讲,GCC对内联函数过于保守,在原始测试用例和上面的示例中都没有inline注释关键字,GCC即使在-fpic/-fPIC使用时也应该发出警告.