Насколько плохо "if (! This)" в функции-члене C ++? - PullRequest
73 голосов
/ 13 января 2012

Если я сталкиваюсь со старым кодом, который содержит if (!this) return; в приложении, насколько серьезен этот риск?Это опасная бомба замедленного действия, требующая немедленного поиска и уничтожения всего приложения, или это больше похоже на запах кода, который можно спокойно оставить на месте?

Я не планирую писать код, который делает это, конечно.Скорее я недавно обнаружил кое-что в старой базовой библиотеке, используемой многими частями нашего приложения.

Представьте, что класс CLookupThingy имеет не виртуальную CThingy *CLookupThingy::Lookup( name ) функцию-член.Видимо, один из программистов в те ковбойские времена сталкивался со многими сбоями, когда NULL CLookupThingy * s передавался из функций, и вместо того, чтобы исправлять сотни сайтов вызовов, он спокойно исправлял Lookup ():

CThingy *CLookupThingy::Lookup( name ) 
{
   if (!this)
   {
      return NULL;
   }
   // else do the lookup code...
}

// now the above can be used like
CLookupThingy *GetLookup() 
{
  if (notReady()) return NULL;
  // else etc...
}

CThingy *pFoo = GetLookup()->Lookup( "foo" ); // will set pFoo to NULL without crashing

Я обнаружил этот драгоценный камень ранее на этой неделе, но сейчас у меня возникает вопрос, должен ли я его починить.Это основная библиотека, используемая всеми нашими приложениями.Некоторые из этих приложений уже были отправлены миллионам клиентов, и, похоже, они работают нормально;в этом коде нет сбоев или других ошибок.Удаление if !this в функции поиска будет означать исправление тысяч сайтов вызовов, которые потенциально проходят NULL;неизбежно некоторые будут пропущены, что приведет к появлению новых ошибок, которые будут появляться случайным образом в течение следующего года разработки.

Так что я склонен оставить это в покое, если в этом нет крайней необходимости.

Учитывая, что это технически неопределенное поведение, насколько опасно if (!this) на практике?Стоит ли исправлять трудозатраты в несколько человеко-недель или можно рассчитывать на MSVC и GCC для безопасного возвращения?

Наше приложение компилируется в MSVC и GCC и работает в Windows, Ubuntu и MacOS.Переносимость на другие платформы не имеет значения.Данная функция гарантированно никогда не будет виртуальной.

Редактировать: Вид объективного ответа, который я ищу, выглядит примерно так:

  • "Текущие версииMSVC и GCC используют ABI, где не виртуальные члены действительно статичны с неявным параметром «this», поэтому они будут безопасно переходить в функцию, даже если «this» имеет значение NULL »или
  • » в следующей версии GCCизмените ABI так, чтобы даже не виртуальные функции требовали загрузки цели ветвления из указателя класса «или
  • », текущий GCC 4.5 имеет несовместимый ABI, где иногда он компилирует не виртуальные члены как прямые ветви с неявным параметром, а иногдав качестве указателей на функции смещения класса. "

Первое означает, что код вонючий, но вряд ли сломается;второе - что-то проверить после обновления компилятора;последнее требует немедленных действий даже при высоких затратах.

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

Ответы [ 11 ]

1 голос
/ 13 января 2012

По моему личному мнению, вы должны как можно раньше потерпеть неудачу, чтобы предупредить вас о проблемах. В этом случае я бы бесцеремонно удалял все случаи if(!this), которые я мог найти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...