Насколько плохо «if (! This)» в функции-члене C ++?

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

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

Представьте, что класс CLookupThingy имеет невиртуальную CThingy * CLookupThingy :: Lookup (name) функцию-член. Очевидно, один из программистов в те времена ковбоя столкнулся со многими сбоями, когда NULL CLookupThingy * передавались из функций, и вместо того, чтобы исправлять сотни сайтов вызовов, он незаметно исправил 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, где иногда он компилирует невиртуальные элементы как прямые ветви с неявным параметром, а иногда как указатели на функции смещения класса ».

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

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

73
задан Crashworks 16 January 2012 в 02:11
поделиться