Подтвердить что ты не робот

Что означает "ломать, когда исключение пусто" означает?

Я обнаружил, что функция автоматического прерывания исключения Visual С++ 2010 была очень полезной в прошлом, и сегодня я просматривал параметры в этом диалоговом окне и обнаружил, что один из типов исключений является "void". Что это значит? Если я выберу это, я перейду на любое исключение, которое выбрано в коде? Если нет, то какой оператор throw вызовет точку останова этого типа?

Visual Studio Exceptions Dialog

Я предполагаю, что более общий последующий вопрос: где я могу найти документацию по этому диалоговому окну и все его варианты?

4b9b3361

Ответ 1

Относительно того, как это работает (как упоминал MSalters), это касается неправильного наименования.

На самом деле он должен быть назван void*, конечно.

Но почему он работает для int*, const char* и т.д. (фактически любого типа указателя, включая указатель на определенные пользователем типы)?

Ну, я могу предположить, что это связано с очень интересной проблемой обработки исключений в С++ - catch(void*) обработчик исключений фактически улавливает исключения типа указателя (cv-compatible)!

Пример:

try
{
   throw "Catch me if you can!";      
}
catch(void* e)
{
   // ...and I can!
   std::cout << "Gotcha!" << std::endl;
}

Здесь мы бросаем char* (в литературе Visual С++ char char*, а не const char*) и улавливаем его void*. И это сработает!

Ответ можно найти в С++ Holy Standard:

§15.3 Обработка исключения

15.3.3 Обработчик является совпадением для объекта исключения типа E, если

...

обработчик имеет тип cv1 T * cv2, а E - тип указателя, который может быть преобразован в тип обработчика одним или обоими из - стандартное преобразование указателя (4.10), не включающее преобразование указателей в частные или защищенные или неоднозначные классы

...

И 4.10 говорит, что стандартное преобразование указателя включает преобразование в void*:

4.10.2 Значение типа "указатель на cv T", где T - тип объекта, может быть преобразовано в указатель типа "указатель" to cv void ".

Отметим также, что отладчик Visual Studio работает аналогичным образом, но не совсем так. Разница в том, что он игнорирует cv-квалификаторы. Таким образом, void в диалоговом окне "Исключения" означает любой [any cv] void*. Обработчики уловов будут не игнорировать их:

try
{
   struct Throwee {};
   const Throwee* t = nullptr;
   throw t;      
}
catch(void* e)
{
   // Will be missed
   std::cout << "Gotcha!" << std::endl;
}
catch(const void* e)
{
   // Will be catched
   std::cout << "Gotcha const!" << std::endl;
}

Ответ 2

Я обнаружил, что он сломается при метании void*, int* или char const*, но не int.

Ответ 3

Может быть, настройка для catch (...). Либо это распространялось throw;.