Вредное полезное предупреждение компилятора
От: _Winnie Россия C++.freerun
Дата: 07.09.04 16:58
Оценка:
.\graphic.h(26): remark #444: destructor for base class "boost::noncopyable" is not virtual
  struct Texture: public boost::noncopyable



В некоторых случаях оно очень полезно — я нашел с его помощью две ошибки. Но иногда оно очень сильно достает — см. выше, когда я точно уверен, что не буду делать delete базовому классу. Что посоветуете?
Правильно работающая программа — просто частный случай Undefined Behavior
Re: Вредное полезное предупреждение компилятора
От: Шахтер Интернет  
Дата: 07.09.04 18:02
Оценка:
Здравствуйте, _Winnie, Вы писали:


_W>
_W>.\graphic.h(26): remark #444: destructor for base class "boost::noncopyable" is not virtual
_W>  struct Texture: public boost::noncopyable
_W>



_W>В некоторых случаях оно очень полезно — я нашел с его помощью две ошибки. Но иногда оно очень сильно достает — см. выше, когда я точно уверен, что не буду делать delete базовому классу. Что посоветуете?


Запрети ключиком, если достаёт.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[2]: Вредное полезное предупреждение компилятора
От: _Winnie Россия C++.freerun
Дата: 07.09.04 21:23
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Запрети ключиком, если достаёт.


Ключиком нельзя, оно тогда везде его отключит.




Забыл сказать. Компилятор — Intel C++ 8.0. Предупреждение, к сожалению, появляется при попытке наследования (неважно, public или private), а не попытке delete к базовому классу. Как я уже сказал, я с его помощью МГНОВЕННО нашел у себя в проекте 2 забытых слова virtual перед деструктором, где оно было необходимо.

Вспомнил, что ICC – это мутант-полукровка из MSVC и EDG.
Пока решил проблему с этим предупреждением так:

//Фуууу... гадость какая...

#ifdef __INTEL_COMPILER
# pragma warning(push)
# pragma warning(disable: 444) //destructor for base class "..." is not virtual
#endif


struct SomeClass: public boost::noncopyable
{
  //внутренности...
};

#ifdef __INTEL_COMPILER
# pragma warning(pop)
#endif

Может, можно без таких извращений?

_W>МГНОВЕННО нашел у себя в проекте 2 забытых слова virtual

Встал вопрос, почему раньше все работало? . Секрет был в том, что я пользовался boost::shared_ptr, а ему (точнее, его deleter) абсолютно пофиг на виртуальность деструктора базового класса.

#include <boost/shared_ptr.hpp>
#include <iostream>

struct A
{
  A() { std::cout <<"A\n"; }
  ~A() { std::cout <<"~A\n"; }
};

struct B: public A
{
  B() { std::cout <<"B\n"; }
  ~B() { std::cout <<"~B\n"; }
};


int main()
{
  {  //OK:
    boost::shared_ptr<A> ptr = boost::shared_ptr<B>(new B);
    ptr.reset();
  }
  std::cout <<"----\n"; 
  {  //UB: (забыли вызвать деструктор производного класса)
    A *ptr= new B;
    delete ptr;
  }
}


Вот так вот
Правильно работающая программа — просто частный случай Undefined Behavior
Re[3]: Вредное полезное предупреждение компилятора
От: Nuald Россия http://nuald.blogspot.com
Дата: 07.09.04 23:29
Оценка:
Здравствуйте, _Winnie, Вы писали:

_W>Забыл сказать. Компилятор — Intel C++ 8.0. Предупреждение, к сожалению, появляется при попытке наследования (неважно, public или private), а не попытке delete к базовому классу. Как я уже сказал, я с его помощью МГНОВЕННО нашел у себя в проекте 2 забытых слова virtual перед деструктором, где оно было необходимо.


Ну так значит преднамеренно объявили деструктор невиртуальным, чтобы никто не наследовал... Вам же надеюсь, не приходит мысль наследовать от std::string — там используется такой же механизм для защиты от наследования.
Re[4]: Вредное полезное предупреждение компилятора
От: ssm Россия  
Дата: 08.09.04 07:07
Оценка:
Здравствуйте, Nuald, Вы писали:

N>Ну так значит преднамеренно объявили деструктор невиртуальным, чтобы никто не наследовал... Вам же надеюсь, не приходит мысль наследовать от std::string — там используется такой же механизм для защиты от наследования.


//  Boost noncopyable.hpp header file  --------------------------------------//

[skiped]
//  Private copy constructor and copy assignment ensure classes derived from
//  class noncopyable cannot be copied.

//  Contributed by Dave Abrahams
[skiped]
Re[4]: Вредное полезное предупреждение компилятора
От: Кодт Россия  
Дата: 08.09.04 08:08
Оценка:
Здравствуйте, Nuald, Вы писали:

N>Ну так значит преднамеренно объявили деструктор невиртуальным, чтобы никто не наследовал... Вам же надеюсь, не приходит мысль наследовать от std::string — там используется такой же механизм для защиты от наследования.


Защита не от наследования класса, а от копирования объектов.

Все POD-типы, а заодно и классы/структуры (по умолчанию) являются моделью Copy Constructible и Assignable.
Но не всегда это осмыслено. Например, для синглетонов.
Вот и приходится совершать работу по предотвращению.
Перекуём баги на фичи!
Re[3]: Вредное полезное предупреждение компилятора
От: Шахтер Интернет  
Дата: 08.09.04 17:39
Оценка: 6 (1)
Здравствуйте, _Winnie, Вы писали:

_W>Здравствуйте, Шахтер, Вы писали:


Ш>>Запрети ключиком, если достаёт.


_W>Ключиком нельзя, оно тогда везде его отключит.


Я делаю так. Помещаю в некий общий заголовок серию строк.

#pragma warning( disable : 4231 ) // extern template
#pragma warning( disable : 4511 ) // copy constructor could not be generated
#pragma warning( disable : 4512 ) // assignment operator could not be generated

...


Если мне нужен зачем-то один из этих варнингов, то я просто комментирую строку и пересобираю проект. Изучаем все подозрительные места. Принимаем меры, если нужно.
Снимаем комментарий и собираем проект снова без warning-мусора.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[4]: Вредное полезное предупреждение компилятора
От: _Winnie Россия C++.freerun
Дата: 08.09.04 18:05
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Здравствуйте, _Winnie, Вы писали:

_W>>Здравствуйте, Шахтер, Вы писали:

Ш>Я делаю так. Помещаю в некий общий заголовок серию строк.


Ш>
Ш>#pragma warning( disable : 4231 ) // extern template
Ш>#pragma warning( disable : 4511 ) // copy constructor could not be generated
Ш>#pragma warning( disable : 4512 ) // assignment operator could not be generated
Ш>


Я тоже так делаю для бесполезных варнигов, типа что выше...
#ifdef _MSC_VER
# pragma warning(disable: 4511) //copy constructor could not be generated
# pragma warning(disable: 4512) //assignment operator could not be generated
#endif

#ifdef __INTEL_COMPILER
# pragma warning(disable: 383) //value copied to temporary, reference to temporary used
# pragma warning(disable: 981) //operands are evaluated in unspecified order
# pragma warning(disable: 1418) //external definition with no prior declaration
#endif


но этот-то не бесполезный...
Видимо, так и сделаю. Жаль.



#ifdef __INTEL_COMPILER
# pragma warning(push)
# pragma warning(disable: 444) //destructor for base class "..." is not virtual
#endif

struct WrapBase 
{
};

template <class Iterator>
struct WrapIter: public WrapBase 
{
  int i;
};

#ifdef __INTEL_COMPILER
# pragma warning(pop)
#endif

//<- вот ЗДЕСЬ два раза инстанцируется шаблон, WrapIter<int> и WrapIter<float>. Тут то мне предупреждение и выдают :(((
int main()
{
    WrapIter<int> x;
    WrapIter<float> y;
}



/*
Так как заранее предсказать, где он нстанцируется шаблон невозможно, то брать в скобки #pragma warning(push)/#pragma warning(pop) определение шаблона не имеет смысла.
Compiling with Intel C++ 8.0
gl_enum.cpp
.\gl_enum.cpp(12): remark #444: destructor for base class "WrapBase" is not virtual
  struct WrapIter: public WrapBase 
                          ^
          detected during instantiation of class "WrapIter<Iterator> [with Iterator=int]" at line 24

.\gl_enum.cpp(12): remark #444: destructor for base class "WrapBase" is not virtual
  struct WrapIter: public WrapBase 
                          ^
          detected during instantiation of class "WrapIter<Iterator> [with Iterator=float]" at line 25


Эххх... Даже не знаю, что делать... Задумка у EDG была хорошая, а вот исполнение...
*/
Правильно работающая программа — просто частный случай Undefined Behavior
Re: Вредное полезное предупреждение компилятора
От: Centaur Россия  
Дата: 29.08.09 09:19
Оценка:
Здравствуйте, _Winnie, Вы писали:

_W>
_W>.\graphic.h(26): remark #444: destructor for base class "boost::noncopyable" is not virtual
_W>  struct Texture: public boost::noncopyable
_W>


_W>В некоторых случаях оно очень полезно — я нашел с его помощью две ошибки. Но иногда оно очень сильно достает — см. выше, когда я точно уверен, что не буду делать delete базовому классу. Что посоветуете?


Некропостер, конечно, чудак, но, кажется, правильного решения в треде нет.

struct Texture: private boost::noncopyable
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.