Я скомпилировал пример кода ниже, чтобы проиллюстрировать проблему, исходя из моего понимания. основной причины (это поведение также описано в статье ThreadSanitizerPopularDataRaces#data-race-on-vptr, и, насколько я понял, в статье говорится, что это ошибка реализации).
Сейчас я пытаюсь выяснить причину соответствующие разделы стандарта, чтобы сделать вывод, является ли это ошибкой компилятора или ошибкой реализации с нашей стороны.
Но поскольку vptr и vtable не определены напрямую в стандарте и в основном представляют собой детали реализации компилятора , мне пока не удалось найти соответствующие разделы стандарта.
Описание проблемы:
Рассмотрите код в приведенном ниже примере (пожалуйста, запишите раздел комментариев, чтобы понять суть проблемы): (то же самое доступно по адресу: https://godbolt.org/z/7Wd5ezPTE)
Код: Выделить всё
#include
#include
class MyInterface {
public:
virtual ~MyInterface() noexcept = default;
virtual void Fun1() noexcept = 0;
};
// Some function that will be called from a dedicated thread based on some events. I have written it as stand-alone function for easier understanding.
void InvokeFun1(MyInterface* ptr) noexcept {
// The sanitizer reports a data race on vptr in the below line when the the object of Myderived2 is being destroyed parallelly from the main thread.
// I know that the vptr and vtable are implementation details, but at least the clang compiler uses the vtable/vptr mechanism internally where this problem is reported.
// WARNING: ThreadSanitizer: data race on vptr (ctor/dtor vs virtual call)
// I am trying to find out from the C++ standard POV, whether the clang-compiler need to make sure the vptr access here atomic?
ptr->Fun1();
}
class Myderived1 : public MyInterface {
public:
~Myderived1() noexcept override {
// Placeholder: Clang-compiler implementation to set vptr to point to the vtable of the current class.
// I am trying to find out from the C++ standard POV, whether the clang-compiler need to make sure the vptr assignment here atomic?
my_thread.join(); // Join the thread to make sure the other thread does not try to invoke the Fun1() which is marked as final in this class
}
// Note the function is marked final here.
void Fun1() noexcept final { std::cout
Подробнее здесь: [url]https://stackoverflow.com/questions/78160803/what-does-the-c-standard-state-about-the-virtual-functions-behavior-during-the[/url]