g ++ — 4.8.1 считает, что явно объявленный деструктор без спецификации исключений всегда noexcept (true)

Рассмотрим следующую программу:

#include <type_traits>

struct Thrower
{
~Thrower() noexcept(false) { throw 1; }
};

struct Implicit
{
Thrower t;
};
static_assert(!std::is_nothrow_destructible<Implicit>::value, "Implicit");

struct Explicit
{
~Explicit() {}

Thrower t;
};
static_assert(!std::is_nothrow_destructible<Explicit>::value, "Explicit");

С g++-4.8.1есть сбой статического утверждения на Explicit — кажется, что ~Explicit() является noexcept, Это не соответствует моим ожиданиям. Согласно §12.4.3:

Объявление деструктора, у которого нет спецификации исключения, неявно
считается, что имеет ту же спецификацию исключений, что и неявное объявление

Самое смешное здесь — проверка Implicit кажется, ведет себя согласно моей интерпретации §15.4.14 (через §12.4.7).

…Если е является … деструктором … это неявная спецификация спецификации исключений … f имеет спецификацию исключений noexcept(true) если каждая функция, которую она вызывает напрямую, не допускает никаких исключений.

g++-4.7 не хватает is_nothrow_destructableЯ написал свой собственный, чтобы проверить поведение в 4.7. Программа вроде отлично компилируется. Я оставляю за собой право на то, что это будет совершенно неправильно и источником моего замешательства:

template <typename T>
struct is_nothrow_destructible
{
static constexpr bool value = noexcept(std::declval<T>().~T());
};

TL; DR: Почему g++-4.8.1 думаю, что явно объявленный деструктор без спецификации исключения всегда noexcept(true)?


ОбновитьЯ открыл ошибку на этом: 57645. Если вам действительно нужно обойти эту проблему, вы можете добавить спецификацию исключений в деструктор (например, Thrower есть в примере).

16

Решение

TL; DR: Почему g ++ — 4.8.1 считает, что явно объявленный деструктор без спецификации исключений всегда noexcept(true)?

Потому что это ошибка?

Ваша интерпретация стандарта верна, и Clang правильно ее реализует (утверждение не срабатывает).

f имеет спецификацию исключения noexcept(true) если каждая функция, которую он непосредственно вызывает не допускает никаких исключений.

Деструктор напрямую вызывает деструктор всех подобъектов:

§12.4 [class.dtor] p8:

После выполнения тела деструктора и уничтожения любых автоматических объектов, размещенных в теле, деструктор для класса X вызывает деструкторы для прямых не вариантных нестатических элементов данных X, […].

7

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

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

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