clang-11 (оптимизированная сборка): почему охват строки gcovr кодом C (скомпилированным с-O2) не составляет 100%

#c

Вопрос:

У меня есть следующий C -код:

  #include<stdexcept>
 #include<string>
 #include<cassert>
 
 class my_exception_t : public std::runtime_error {
    public:
     my_exception_t();
     ~my_exception_t() noexcept override;
 };
 
 class my_other_exception_t : public std::runtime_error {
    public:
     my_other_exception_t();
     ~my_other_exception_t() noexcept override;
 };
 
 class my_sub_exception_t : public my_exception_t {
    public:
     my_sub_exception_t();
     ~my_sub_exception_t() noexcept override;
 };
 
 my_exception_t::my_exception_t()
     : std::runtime_error("my-exception") {}
 my_exception_t::~my_exception_t() noexcept = defau<
 
 my_other_exception_t::my_other_exception_t()
     : std::runtime_error("my-other-exception") {}
 my_other_exception_t::~my_other_exception_t() noexcept = defau<
 
 my_sub_exception_t::my_sub_exception_t() : my_exception_t{} {}
 my_sub_exception_t::~my_sub_exception_t() noexcept = defau<
 
 int main() {
     //TEST 1
     static_assert(std::is_base_of<std::runtime_error,
                                   my_exception_t>::value);
     my_exception_t me;
 
     //TEST 2
     static_assert(std::is_base_of<std::runtime_error,
                                   my_other_exception_t>::value);
     my_other_exception_t moe;
 
     //TEST 3
     static_assert(std::is_base_of<std::runtime_error,
                                   my_sub_exception_t>::value);
     static_assert(std::is_base_of<my_exception_t,
                                   my_sub_exception_t>::value);
     my_sub_exception_t mse;
 }
 

Это работает, как и ожидалось, но я также хочу проверить покрытие кода!
Но когда я компилирую код с clang -11 и флагами -O2 , выполняю двоичный файл и запускаю govr его, я вижу, что строка с определением деструкта ~my_sub_exception() не покрыта:

Я выполняю следующие вызовы:

 $ clang  -11 -O2 -coverage -Weverything -Wno-c  98-compat -Wno-c  98-compat-pedantic -Wno-padded -Werror -pedantic-errors -Wno-global-constructors -std=c  17 -o ex.cpp.o -c ex.cpp
$ clang  -11 ex.cpp.o -o ex -coverage
$ ./ex
$ gcovr -r . --gcov-executable="llvm-cov-11 gcov"
------------------------------------------------------------------------------
                           GCC Code Coverage Report
Directory: .
------------------------------------------------------------------------------
File                                       Lines    Exec  Cover   Missing
------------------------------------------------------------------------------
ex.cpp                                        13      12    92%   32
------------------------------------------------------------------------------
TOTAL                                         13      12    92%
------------------------------------------------------------------------------
 

Примечание: Я получаю полное покрытие, если использую clang -11 с -O0 .
(Я также получаю полное покрытие, если использую g -11 оба -O2 и -O0 ).
Но почему бы не для clang -11 с -O2 ?

Насколько я заметил проблему, я получаю эту непокрытую строку только для исключений, которые наследуются от my_exception_t . Если класс исключения унаследован от std::runtime_error , то покрытие строки не отсутствует.

Комментарии:

1.Мне интересно, как clang -11 с -O2 устранит ваши тестовые случаи

Ответ №1:

Возможно, из-за того, что все ваши my_exception s являются глобальными (статическими) переменными, и, следовательно, нет необходимости что-либо уничтожать (они просто исчезнут, когда процесс завершится).

Чтобы действительно ответить, вам придется нанять своего собственного юриста по языку C и эксперта по clang .

Комментарии:

1. Но я нигде не вижу статических переменных в этом коде. И почему деструктор вызывается для исключений, от которых наследуется directy std::runtime_error ?