Try\catch в функции main() без скобок

Visual Studio 2015; Язык С++.

Я помню, что я где-то читал о точке входа (т.е. метод main), что можно написать:

#include <iostream>
using namespace std;

int main()
try{
  return 0; // I am here...
}
catch (...){
  cout << "I am 'catch'..." << endl; // This row wasn't called!
  return 1; // Oops... But the next `F10` key pressing jumps from the "try" 
  // block into this row!
}

т.е. в этом случае блок try\catch находится не в скобках:

int main() { // start bracket
  try{
    return 0;
  }
  catch (...){
    return 1;
  }
} // end bracket

Оба случая скомпилированы и работают тоже, но... В первом варианте, когда я шаг за шагом нажимаю клавишу F10 после блока try, я также попадаю в блок catch. Для второго варианта кода у меня нет такого поведения.

Почему это происходит?

Ответ 1

Ваша конструкция является функцией-try-block и определена в drafs n4296 для спецификации С++ 11 в 8.4. Определения функций [dcl.fct.def.general] с помощью:

Определения функций имеют вид

  • Функция-определение:
    • атрибут-specifier-seq opt decl-specifier-seq opt declarator virt-specifier-seq opt function-body
  • Функция тела:
    • ctor-initializer opt составной оператор
    • Функция попробуйте-блок
    • = default;
    • = delete;

а затем в 15 Обработка исключений [кроме] с помощью:

Функция-примерочный блок:

  • попробуйте ctor-initializer opt обработчик составных операторов-seq

Примеры предполагают, что нормальное использование для функции-try-блока должно быть ctor, но оно справедливо для нормальной функции (и основная синтаксически простая функция)

Он действителен и работает нормально, что означает, что блок catch оценивается только в том случае, если исключение происходит в ctor-initializer opt в составном заявлении. Вы можете подтвердить это в своем коде, добавив отпечатки в свои блоки или проверив возвращаемое значение.

В системе Unix

foo
echo $?

должен эхо 0

В системе Windows под окнами CMD.exe

foo.exe
if errorlevel 1 echo "Catch block"

не выводить Catch block

Если ваш отладчик позволяет выполнять команды выполнить в блоке catch... это не соответствует С++ 11!

Но известно, что при выходе из блока отладчик MSVC помещает курсор в последнюю строку блока, я предполагаю, что это то, что происходит здесь, потому что последняя строка функции-try-block равна последняя строка catch.

Ответ 2

В С++ Spec указано следующее:

Функция-try-block связывает обработчик-seq с ctor-initializer, если присутствует, и составной оператор. Исключение, возникшее во время выполнения составного заявления, или для конструкторы и деструкторы, во время инициализации или соответственно, уничтожения объектов субъектов классов, переносов управление обработчиком в функции-try-block так же, как исключение, возникшее во время выполнения контроля передачи try-блоков для других обработчиков.

Нет специального использования для использования/поведения блока try функции в конструкторе или любой другой функции.