以下是我的代码的缩减版本,用于unique_pointer
类似的实现仍然存在问题:
#include <tr1/type_traits>
template<typename T>
class rv : public T {
rv();
~rv();
rv( rv const& );
rv& operator=( rv const& );
};
template<typename T,typename D,bool = std::tr1::is_empty<D>::value>
struct pjl_ptr_storage {
};
template<typename T,typename D>
struct pjl_ptr_storage<T,D,true> : private D {
T *ptr_;
pjl_ptr_storage( T *p ) : ptr_( p ) { }
pjl_ptr_storage( T *p, D &d ) : D( d ), ptr_( p ) { }
D& deleter() { return *this; }
};
template<typename T>
struct default_delete {
};
template<typename T,class D = default_delete<T> >
class pjl_ptr {
public:
explicit pjl_ptr( T *p = 0 ) : storage_( p ) { }
pjl_ptr( rv<pjl_ptr> &p ) : storage_( p.release(), p.storage_.deleter() ) { }
T* release() {
T *temp = storage_.ptr_;
storage_.ptr_ = 0; // dereferencing pointer ‘<anonymous>’ breaks strict-aliasing rules
return temp;
}
operator rv<pjl_ptr>&() {
return *static_cast<rv<pjl_ptr>*>( this );
}
private:
pjl_ptr_storage<T,D> storage_;
pjl_ptr( pjl_ptr& ); // forbid
};
///////////////////////////////////////////////////////////////////////////////
typedef pjl_ptr<int> int_ptr;
int_ptr f() {
return int_ptr( 0 ); // this line triggers the warning above
}
int main() {
}
使用使用-O2 -fstrict-aliasing -Wstrict-aliasing
编译的g ++ 4.4.3,我在上面标记的行上得到:dereferencing pointer <anonymous> breaks strict-aliasing rules
。这恰好发生在Ubuntu 64位系统上。如果我在Mac OS X Lion上使用g ++ 4.6.1编译相同的代码,我没有得到任何警告。
我一般都理解严格别名规则(或者我认为),但我不明白为什么它会抱怨这条线。
g ++ 4.4.3错了吗?假设它是正确的,我如何调整代码以消除警告,即不破坏严格别名规则?
答案 0 :(得分:0)
gcc
不喜欢您投射this
(您可以尝试将this
替换为0
,并查看警告是否会消失;我认为它会)。所以你有两个指向同一个内存但有不同类型的指针(pjl_ptr
和rv<pjl_ptr>
)。 gcc警告您(例如,由于某些优化)通过rv<pjl_ptr>
指针进行的更改(例如,分配给storage_.ptr_
)可能会通过pjl_ptr
指针无法看到。
就我个人而言,我看不出它会如何导致您的问题,但看起来gcc是正确的。
PS。我不是一个标准的大师,所以我不知道究竟是什么标准考虑它:)
答案 1 :(得分:0)
我不知道你要做什么。
template<typename T>
class rv : public T {
// private: by default
rv();
~rv();
rv( rv const& );
rv& operator=( rv const& );
};
没有可访问的ctor,也没有朋友。你不可能拥有该类的实例。