C++23 - Каковы преимущества класса stacktrace_entry?
Когда этот класс в файле заголовка будет добавлен к языку, с какими проблемами мы сможем справиться легче и какие синтаксисы планируется заменить? Ниже я делюсь кодом, полученным с веб-сайта cppreference .
Класс std::stacktrace_entry
namespace std {
class stacktrace_entry {
public:
using native_handle_type = /* implementation-defined */;
// constructors
constexpr stacktrace_entry() noexcept;
constexpr stacktrace_entry(const stacktrace_entry& other) noexcept;
constexpr stacktrace_entry& operator=(const stacktrace_entry& other) noexcept;
~stacktrace_entry();
// observers
constexpr native_handle_type native_handle() const noexcept;
constexpr explicit operator bool() const noexcept;
// query
string description() const;
string source_file() const;
uint_least32_t source_line() const;
// comparison
friend constexpr bool operator==(const stacktrace_entry& x,
const stacktrace_entry& y) noexcept;
friend constexpr strong_ordering operator<=>(const stacktrace_entry& x,
const stacktrace_entry& y) noexcept;
};
}
2 ответа
Когда вы подключаетесь к программе C++ с помощью отладчика и останавливаете выполнение, одна вещь, которую относительно легко сделать (с некоторыми инструментами времени компиляции), - это обработать стек вызовов кода в заданной точке.
В общем, реализация C++ состоит в том, что стек вызовов представляет собой связанный список (возможно, сохраненный нетривиальным образом), где, когда вы возвращаетесь из функции, вы переходите в то место, которое вызывающий ввел, когда он позвонил вам.
Эти адреса могут быть декодированы отладчиком, затем местоположения инструкций могут быть сопоставлены с исходными местоположениями C++, и может быть сгенерировано красивое изображение того, как вы попали в эту строку кода . В зависимости от настроек оптимизации эта информация может иногда быть неточной, отсутствовать некоторые кадры или полная ерунда; но это очень полезно.
Даже без инструментария времени компиляции цепочка указателей инструкций может быть сохранена, и тогда кто-нибудь, у кого есть инструментарий времени компиляции, сможет довольно хорошо ее декодировать.
Существуют библиотеки, которые позволяют программам на C++ делать это внутренне, без внешнего отладчика. К ним относится библиотека boost stacktrace.
Это добавляет эту возможность к
std
библиотека.
Трассировка стека - это цепочка фреймов, и эта новая часть стандартной библиотеки может отображать фреймы в исходный файл, имя функции и информацию о номере строки.
Типичным вариантом использования может быть обнаружение ситуаций, когда программа ведет себя недопустимым образом в исходном коде C++, и создание журнала, чтобы сообщить об этом перед попыткой восстановления, или просто выполнить выход. Затем программисты могут просмотреть эту трассировку стека и получить информацию о том, как исправить эту ошибку.
stacktrace
описывает компоненты, которые программы C++ могут использовать для хранения трассировки стека текущего потока выполнения и запроса информации о сохраненной трассировке стека во время выполнения.
stacktrace_entry class
предоставляет операции для запроса информации об оценке в трассировке стека. Каждый объект stacktrace_entry либо пуст, либо представляет собой оценку в stacktrace.
stacktrace
является приблизительным представлением последовательности вызовов и состоит из записей трассировки стека. Запись stacktrace представляет собой оценку в stacktrace.
Синопсис заголовка "stacktrace"
namespace std {
class stacktrace_entry;
template<class Allocator>
class basic_stacktrace;
using stacktrace = basic_stacktrace<allocator<stacktrace_entry>>;
template<class Allocator>
void swap(basic_stacktrace<Allocator>& a, basic_stacktrace<Allocator>& b)
noexcept(noexcept(a.swap(b)));
string to_string(const stacktrace_entry& f);
template<class Allocator>
string to_string(const basic_stacktrace<Allocator>& st);
template<class charT, class traits>
basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const stacktrace_entry& f);
template<class charT, class traits, class Allocator>
basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const basic_stacktrace<Allocator>& st);
template<class T> struct hash;
template<> struct hash<stacktrace_entry>;
template<class Allocator> struct hash<basic_stacktrace<Allocator>>;
}
Обзор класса stacktrace_entry
namespace std {
class stacktrace_entry {
public:
using native_handle_type = implementation-defined;
// constructors
constexpr stacktrace_entry() noexcept;
constexpr stacktrace_entry(const stacktrace_entry& other) noexcept;
constexpr stacktrace_entry& operator=(const stacktrace_entry& other) noexcept;
~stacktrace_entry();
// observers
constexpr native_handle_type native_handle() const noexcept;
constexpr explicit operator bool() const noexcept;
// query
string description() const;
string source_file() const;
uint_least32_t source_line() const;
// comparison
friend constexpr bool operator==(const stacktrace_entry& x, const stacktrace_entry& y) noexcept;
friend constexpr strong_ordering operator<=>(const stacktrace_entry& x, const stacktrace_entry& y) noexcept;
};
}
Объект типа stacktrace_entry либо пуст, либо представляет собой запись stacktrace и предоставляет операции для запроса информации о ней.
Наблюдатели
constexpr native_handle_type native_handle() const noexcept;
Семантика этой функции определяется реализацией. Примечание. Последовательные вызовы функции native_handle для неизмененного объекта stacktrace_entry возвращают идентичные значения.
constexpr explicit operator bool() const noexcept;
Возвращает false тогда и только тогда, когда пусто.
Запрос
Все функции запроса stacktrace_entry обрабатывают ошибки, отличные от ошибок выделения памяти, как «отсутствие информации» и в этом случае не вызывают.
string description() const;
возвращает описание оценки, представленной
*this
, или
empty string
. бросает
bad_alloc
если память для внутренних структур данных или результирующей строки не может быть выделена.
string source_file() const;
выбрасывает, если память для внутренних структур данных или результирующая строка не может быть выделена.
uint_least32_t source_line() const;
возвращается
0
, или
1
номер строки, который лексически относится к оценке, представленной * this. Если исходный_файл возвращает предполагаемое имя исходного файла, возвращает предполагаемый номер строки; если исходный_файл возвращает фактическое имя исходного файла, возвращает фактический номер строки.
bad_alloc
если память для внутренних структур данных не может быть выделена.
Сравнение
friend constexpr bool operator==(const stacktrace_entry& x, const stacktrace_entry& y) noexcept;
возвращается
true
тогда и только тогда, когда они представляют одну и ту же запись трассировки стека или обе
x
а также
y
пусты.
Рекомендации