#c #gcc #compiler-errors #compilation #clang
#c #gcc #ошибки компилятора #Сборник #лязг
Вопрос:
В следующем примере программа использует локальную переменную шаблона потока и создает ее экземпляр, используя тип внутри анонимного пространства имен. Это приводит к ошибке компоновщика в gcc
. В clang
нем фактически компилируется, но выполняется некорректно.
#include <stdio.h>
template<typename T>
struct container {
container() { printf("construct: %pn", this); }
~container() { printf("destruct: %pn", this); }
};
template<typename T>
thread_local container<T> storage;
namespace {
struct bar {};
}
int main() {
autoamp; ref1 = storage<bar>;
autoamp; ref2 = storage<bar>;
}
В gcc это приводит к ошибке ссылки:
a.cpp:6:2: warning: ‘container<T>::~container() noexcept [with T = {anonymous}::bar]’ used but never defined
~container() { printf("destruct: %pn", this); }
^
/tmp/ccgh0P15.o: In function `__tls_init':
a.cpp:(.text 0xa9): undefined reference to `container<(anonymous namespace)::bar>::~container()'
С clang программа компилируется, но выдает очень тревожный результат:
construct: 0x7fb8d1c003d0
construct: 0x7fb8d1c003d0
destruct: 0x7fb8d1c003d0
destruct: 0x7fb8d1c003d0
Есть ли какие-то неровности, связанные с переменными thread_local / templated, с которыми я сталкиваюсь здесь? Мне непонятно, почему это когда-либо приведет к ошибке ссылки (ошибка ссылки исчезает, если я удаляю thread_local). В случае clang как двойное уничтожение объекта со статической продолжительностью хранения может быть чем угодно, кроме ошибки компилятора? В clang проблема исчезает, если я удаляю анонимное пространство имен ИЛИ спецификацию thread_local ИЛИ удаляю одну из ссылок в main() .
Может кто-нибудь пролить некоторый свет на это, мне в основном просто любопытно, если я что-то недопонимаю. Спасибо!
Редактировать:
clang -v
Apple LLVM version 10.0.0 (clang-1000.11.45.5)
g -v
gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
Комментарии:
1. Это вся программа.
2. Хорошо, это действительно довольно интересно. Я предполагаю, что вас беспокоит вывод clang в том, что ctor / dtor, по-видимому, выполняется дважды?
3. Да, я должен был быть немного более ясным. Объект создается дважды, а затем дважды уничтожается, что мне определенно кажется недопустимым.
4. Кроме того, не обращайте внимания на мой комментарий из дальнейшего, касающийся UB, я написал это, основываясь на неправильном понимании того, что вы здесь делаете.