Domanda

I have next code:

#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;
}

And with next options:
-fno-pic -fmessage-length=0 -std=c++0x -Wnoexcept
g++ throw next warnings:

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]

But why when I use -fpic instead of -fno-pic g++ doesn't throw any warnings?

EDIT:
GCC version - 4.7.2

È stato utile?

Soluzione

The warning is not issued in the -fpic case, because the compiler assumes that the constructor A::A() can throw.

When compiling PIC code, GCC assumes that every global name can be overridden by symbols from other modules. Hence, with absence of an explicit noexcept declaration, GCC must conservatively assume that such a function can throw exceptions, even if it can statically prove that the version it's seeing now, cannot.

For reference, see the bug and the patch here http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29323#c7 (code has changed a little since, but it started like this)

An example, where the above is applicable:

/* inline */ int f() { return 0; }

int g() noexcept (noexcept(f())) { return f() + 1; }

So, this is the immediate reason "why" there's no warning. What follows is what I think about it.

However, C++11 says:

7.1.2 Function specifiers [dcl.fct.spec]

4 An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case (3.2).

i.e. for inline functions, if a function is determined to not throw, GCC can assume that every potential override of such a function cannot throw as well.

In that sense, GCC is being excessively conservative with inline functions and both in the original test case and in the above example with the inline keyword uncommented, GCC ought to issue the warning even when -fpic/-fPIC is used.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top