Почему g ++ не генерирует связанное с конструктором предупреждение noexcept с включенным `-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;
}

И со следующими вариантами:
-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

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

Таким образом, это непосредственная причина «почему», здесь нет предупреждения. Далее следует то, что я думаю об этом.

Тем не менее, C ++ 11 говорит:

7.1.2 Спецификаторы функций [dcl.fct.spec]

4 Встроенная функция должна быть определена в каждой единице перевода в
который используется Odr и должно иметь точно такое же определение в
каждый случай
(3.2).

то есть для встроенных функций, если определено, что функция не выбрасывает, GCC может предположить, что каждое потенциальное переопределение такой функции также не может генерировать.

В этом смысле GCC чрезмерно консервативен со встроенными функциями и как в исходном тестовом примере, так и в приведенном выше примере с inline ключевое слово без комментариев, GCC должен выдавать предупреждение, даже если -fpic/-fPIC используется.

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]