在没有括号的main()函数中尝试\ catch块

And*_*man 11 c++ try-catch

Visual Studio 2015; C++语言.

我记得我在某处读到了关于入口点(即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!
}
Run Code Online (Sandbox Code Playgroud)

即在这种情况下,try\catch块不在括号中:

int main() { // start bracket
  try{
    return 0;
  }
  catch (...){
    return 1;
  }
} // end bracket
Run Code Online (Sandbox Code Playgroud)

这两种情况都是成功编译并且也可以工作,但是......在第一个版本中,当我逐步按下F10按键后,trycatch也进入了块.对于代码的第二个变体,我没有这样的行为.

为什么会这样?

Ser*_*sta 9

你的构造是一个函数try-block,在drafs n4296中为C++ 11规范定义,8.4函数定义[dcl.fct.def.general]:

函数定义具有形式

  • 函数的定义:
    • attribute-specifier-seq opt decl-specifier-seq opt declarator virt-specifier-seq opt function-body
  • 函数体:
    • ctor-initializer opt复合语句
    • 功能试块
    • =默认;
    • =删除;

后来在15个异常处理[除]中:

功能试块:

  • 尝试ctor-initializer opt复合语句handler-seq

示例表明函数try-block的正常用法应该是ctor,但它对正常函数有效(而main在语法上只是一个函数)

它是有效且正常工作,这意味着只有在复合语句中的ctor-initializer opt on中发生异常时才会计算catch块.您可以在代码中通过在块中添加打印件或通过测试返回值来确认它.

在类似Unix的系统中

foo
echo $?
Run Code Online (Sandbox Code Playgroud)

应该回应 0

在CMD.exe窗口下的Windows系统中

foo.exe
if errorlevel 1 echo "Catch block"
Run Code Online (Sandbox Code Playgroud)

不应该输出 Catch block

如果您的调试器允许您在catch块中执行指令...它不符合C++ 11!

但是众所周知,当退出一个块时,MSVC调试器将光标放在块的最后一行,我认为这就是这里发生的事情,因为函数try块最后一行是catch的最后一行.