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 пусты.

Рекомендации

Ссылка-1Ссылка-2Ссылка-3

Другие вопросы по тегам