Странное C ++ предупреждение о строгом псевдониме - PullRequest
3 голосов
/ 20 ноября 2011

Ниже приведена упрощенная версия моего кода для реализации класса, подобного 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() {
}

Использование g ++ 4.4.3, скомпилированного с -O2 -fstrict-aliasing -Wstrict-aliasing, Iget: dereferencing pointer <anonymous> breaks strict-aliasing rules в строке с тегом выше.Это происходит в 64-битной системе Ubuntu.Если я скомпилирую тот же код с помощью g ++ 4.6.1 на Mac OS X Lion, я не получу предупреждения.

Я понимаю правила строгого наложения в целом (или мне так кажется), но я не понимаю, почемуон жалуется на обсуждаемую строку.

G ++ 4.4.3 не так?Если предположить, что это правильно, как я могу настроить код, чтобы избавиться от предупреждения, то есть не нарушать правила строгого наложения имен?

Ответы [ 2 ]

0 голосов
/ 13 декабря 2011

Понятия не имею, что вы пытаетесь сделать.

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

Нет доступных ctor и нет друзей.Вы не можете иметь экземпляр этого класса.

0 голосов
/ 20 ноября 2011

gcc не нравится, что вы разыгрываете this (Вы можете попробовать заменить this, например, 0 и посмотреть, исчезнет ли предупреждение; я думаю, что оно исчезнет).Таким образом, у вас есть два указателя на одну и ту же память, но с разными типами (pjl_ptr и rv<pjl_ptr>).gcc предупреждает вас, что (например, из-за некоторых оптимизаций) изменения, сделанные через указатель rv<pjl_ptr> (например, присвоение storage_.ptr_), могут стать невидимыми через указатель pjl_ptr.

Лично я не вижу, как этоможет привести к проблеме в вашем случае, но похоже, что gcc является правильным.

PS.Я не стандартный гуру, так что я не знаю, что именно стандартные думают об этом :)

...