3

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 ‘&lt;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() {
}

でコンパイルされた g++ 4.4.3 を使用すると-O2 -fstrict-aliasing -Wstrict-aliasingdereferencing pointer <anonymous> breaks strict-aliasing rules上記のタグが付いた行で次のようになります。これはたまたま Ubuntu 64 ビット システム上にあります。Mac OS X Lion で g++ 4.6.1 を使用して同じコードをコンパイルしても、警告は表示されません。

厳密なエイリアス規則は一般的に理解しています (またはそう思う) が、問題の行について不平を言っている理由がわかりません。

g++ 4.4.3 は間違っていますか? それが正しいと仮定すると、どのようにコードを微調整して警告を取り除くことができますか?

4

2 に答える 2

0

gccあなたがキャストするのが好きではありません(たとえば、thisに置き換えてみて、警告が消えるかどうかを確認できます。消えると思います)。したがって、同じメモリへの 2 つのポインターがありますが、型が異なります (および)。gcc は、(たとえば、いくつかの最適化のために)ポインターを介して行われた変更 (たとえば、への代入) がポインターを介して見えなくなる可能性があることを警告します。this0pjl_ptrrv<pjl_ptr>rv<pjl_ptr>storage_.ptr_pjl_ptr

個人的には、あなたのケースでどのように問題が発生するのかわかりませんが、gcc は正しいようです。

PS。私は標準の第一人者ではないので、正確に標準が何を考えているのかわかりません:)

于 2011-11-19T22:14:23.667 に答える
0

あなたが何をしようとしているのかわからない。

template<typename T>
class rv : public T {
// private: by default
  rv();
  ~rv();
  rv( rv const& );
  rv& operator=( rv const& );
};

近づきやすい役者も友達もいません。そのクラスのインスタンスを持つことはできません。

于 2011-12-13T08:24:28.290 に答える