Алексей Кутумов, c++ без исключений, часть 3
TRANSCRIPT
![Page 1: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/1.jpg)
C++ WITHOUT EXCEPTIONS, PART 3
Alexey KutumovSenior software engineer at Kaspersky Lab
![Page 2: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/2.jpg)
AGENDA
Зачем нужен C++ без исключений
Ограничения и проблемы
Решение проблем
…
Profit!
![Page 3: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/3.jpg)
ЗАЧЕМ НУЖЕН C++ БЕЗ ИСКЛЮЧЕНИЙ
![Page 4: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/4.jpg)
C++ БЕЗ ИСКЛЮЧЕНИЙ
try { throw std::logic_error(""); } catch (...) { // handle error }
error C2980: C++ exception handling is not supported with /kernel
![Page 5: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/5.jpg)
C++ БЕЗ ИСКЛЮЧЕНИЙ
System programming
Game development
High-performance software (trading systems)
![Page 6: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/6.jpg)
ОГРАНИЧЕНИЯ
![Page 7: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/7.jpg)
ОГРАНИЧЕНИЯ
std::string message{"This string should be long enough..."};
![Page 8: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/8.jpg)
ОГРАНИЧЕНИЯ
std::error_condition ec;nestl::string message{"This string should be long enough...", ec};if (ec) { // handle error}
![Page 9: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/9.jpg)
ОГРАНИЧЕНИЯ
std::error_condition ec;nestl::string message{"This string should be long enough...", ec};if (ec) { // handle error}
nestl::string message2;message2 = message;
![Page 10: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/10.jpg)
ОГРАНИЧЕНИЯ
std::error_condition ec;nestl::string message{"This string should be long enough...", ec};if (ec) { // handle error}
nestl::string message2;message2.assign_copy(message, ec);
![Page 11: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/11.jpg)
ОГРАНИЧЕНИЯ
Есть исключения Нет исключенийОперация кидает исключение Операция возвращает ошибкуКонструктор копирования Двухфазная инициализацияОператор присваивания Явный метод копирования
![Page 12: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/12.jpg)
ПРОБЛЕМЫ
![Page 13: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/13.jpg)
ПРОБЛЕМЫ
С++ без исключений вынуждает программиста ослаблять инварианты
класса
![Page 14: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/14.jpg)
ПРОБЛЕМЫ
struct MyClass { explicit MyClass(std::unique_ptr<Connection>&& connection) { if (!connection) { throw std::logic_error("connection is empty"); } m_connection = std::move(connection); }
std::unique_ptr<Connection> m_connection;};
![Page 15: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/15.jpg)
ПРОБЛЕМЫ
С++ без исключений вынуждает программиста писать больше кода
![Page 16: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/16.jpg)
ПРОБЛЕМЫ
#define TRY(expr) expr; if (ec) {return;}
// without exceptions
TRY(msg2.assign_copy(msg, ec));
TRY(Foo(msg, ec));TRY(Bar(msg2, ec));TRY(Baz(42, ec));
// with exceptions
msg2 = msg;
Foo(msg);Bar(msg2);Baz(42);
![Page 17: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/17.jpg)
ПРОБЛЕМЫ
struct Message { nestl::string id; nestl::vector<int> data;
void assign_copy(const Message& other, std::error_condition& ec) { TRY(id.assign_copy(other.id, ec)); TRY(data.assign_copy(other.data, ec)); }};
![Page 18: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/18.jpg)
FUTURE
compile-time reflection
magic_get (C++-14/C++-17) от Антона Полухина
![Page 19: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/19.jpg)
CURRENT
noexcept (part of function type since C++-17)
std::move
std::is_nothrow_constructible (default, copy, move)
std::is_nothrow_assignable (copy, move)
std::is_nothrow_swappable (since C++-17)
![Page 20: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/20.jpg)
NOEXCEPT PROPAGATION
struct SimpleData { SimpleData() noexcept : x(42) {}
int x;};
struct CompositeData { SimpleData d; float f;};
static_assert(std::is_nothrow_default_constructible_v<SimpleData>, "");static_assert(std::is_nothrow_default_constructible_v<CompositeData>, "");
![Page 21: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/21.jpg)
ДЛЯ ЧЕГО НУЖНЫ TYPE_TRAITS
nestl::vector<Message> msgList;nestl::vector<CompositeData> dataList;
Message msg = get_message();CompositeData data = get_data();
std::error_condition ec;TRY(msgList.push_back_nothrow(msg, ec));TRY(dataList.push_back_nothrow(data, ec));
![Page 22: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/22.jpg)
VECTOR::PUSH_BACK_NOTHROW
void push_back_nothrow(const value_type& val, std::error_condition& ec) { TRY(reallocate_nothrow(size() + 1, ec)); TRY(copy_construct_nothrow(data() + size(), val, ec));
this->m_last += 1;}
![Page 23: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/23.jpg)
COPY_CONSTRUCT_NOTHROW
template <typename T>typename std::enable_if<std::is_nothrow_copy_constructible_v<T>>::typecopy_construct_nothrow(void* position, const T& val, std::error_condition& /* ec */) { new(position) T(val);}
template <typename T>
typename std::enable_if<!std::is_nothrow_copy_constructible_v<T>>::type
copy_construct_nothrow(void* position, const T& val, std::error_condition& ec) { T* obj = new(position) T(); // NOTE: default ctor obj->assign_copy(val, ec); if (ec) { obj->~T(); }}
![Page 24: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/24.jpg)
C++ WITH EXCEPTIONS
library sources
Kernel mode driver
no exceptions
user mode application
has exceptions
EFI mode driver
no exceptions
![Page 25: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/25.jpg)
C++ WITH EXCEPTIONS
struct Message { nestl::string id; nestl::vector<int> data;
void assign_copy(const Message& other, std::error_condition& ec) { TRY(id.assign_copy(other.id, ec)); TRY(data.assign_copy(other.data, ec)); }};
![Page 26: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/26.jpg)
C++ WITH EXCEPTIONS
template <typename T>struct allocator { T* allocate(size_t count); // only if has exceptions void deallocate(T* location, size_t count); // only if has exceptions T* allocate_nothrow(size_t count) noexcept; void deallocate_nothrow(T* location, size_t count) noexcept;};
template <typename Allocator>struct allocator_traits { static pointer allocate(Allocator& a, size_t count); // only if has exceptions static pointer allocate_nothrow(Allocator& a, size_t count) noexcept;};
![Page 27: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/27.jpg)
C++ WITH EXCEPTIONS
template <typename T, typename Allocator>struct vector_base { iterator begin();};
template <typename T, typename Allocator>struct vector_nx : public vector_base<T, Allocator> { void push_back_nothrow(const value_type& val, std::error_condition& ec) noexcept;};
template <typename T, typename Allocator>struct vector_x : public vector_nx<T, Allocator> { void push_back(const value_type& val);};
![Page 28: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/28.jpg)
C++ WITH EXCEPTIONS
template <typename VectorBase>struct vector_nx : public VectorBase { void push_back_nothrow(const value_type& val, std::error_condition& ec) noexcept;};
template <typename VectorBase>struct vector_x : public VectorBase { void push_back(const value_type& val);};
![Page 29: Алексей Кутумов, C++ без исключений, часть 3](https://reader034.vdocuments.mx/reader034/viewer/2022052514/58b8806b1a28ab44078b5d01/html5/thumbnails/29.jpg)
C++ WITH EXCEPTIONS
struct system_exception_support : std::integral_constant<bool, NESTL_HAS_EXCEPTIONS == 1>{};
template <typename T, typename Allocator = nestl::allocator<T>>using vector = typename or_<system_exception_support::value, vector_x<T, Allocator>, vector_nx<T, Allocator>>::type;