我正在开发一个多平台、多编译器库。该库具有以下宏:
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
# pragma intrinsic(_ReadWriteBarrier)
# define MEMORY_BARRIER() _ReadWriteBarrier()
#elif ...
#elif defined(__GNUC__)
# define MEMORY_BARRIER() __asm__ __volatile__ ("" ::: "memory")
#else
# define MEMORY_BARRIER()
#endif
在 GCC 下,上面的代码可以用来驯服优化器。虽然调用了函数MEMORY_BARRIER
,但重要的部分是标记的内联汇编volatile
。这是在 GCC、Clang 和 Intel 下驯服优化器的部分。
编辑:内联程序集不会驯服 Clang 上的优化器,即使 Clang 通过定义__GNUC__
. 请参阅LLVM 错误 15495 - 死存储传递忽略内存破坏 asm 语句。
宏的使用是一个handle
类。提供handle
了一个级别和间接性,我们试图诱导一个 NULL 指针取消引用来帮助定位错误(一些手放弃)。为了实现我们的目标,我们需要确保优化器不会删除死存储(m_p = NULL;
):
template <class T> handle<T>::~handle()
{
delete m_p;
m_p = NULL;
MEMORY_BARRIER();
}
我不想使用volatile
演员表,因为(1)我不相信它对限定符的正确使用(取自与 Clang 和 GCC 开发人员的交互),以及(2)看起来volatile
演员表是 C++ 中未定义的行为(请参阅已批准的避免左值转换警告和错误的方法?)。
内存屏障是否驯服了 Microsoft 平台上的优化器?