尝试在main()函数中使用不带括号的catch块

trycatch block in the main() function without brackets

本文关键字:catch main 函数      更新时间:2023-10-16

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!
}

。在这种情况下,trycatch块不在括号内:

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

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

为什么会发生?

你的构造是一个 Function -try-block,在c++ 11规范的n4296草案8.4 Function definitions [dcl.fct.def.general]中定义:

函数定义的形式为

  • 函数定义:
    • 属性-指定符-seqopt decl-指定符-seqopt声明符virt-指定符-seqopt function-body
  • 函数体:
    • ctor-initializer <子>选择复合语句
    • function-try-block

及以后版本15异常处理[except] with:

function-try-block:

  • 尝试变量初始化opt复合语句处理程序-seq

示例表明,函数-try-block的正常用法应该是一个actor,但它对一个普通函数也是有效的(并且main在语法上仅仅是一个函数)

有效且正常工作,这意味着只有在复合语句中的opt on的变量初始化器中出现异常时,才会计算catch块。您可以在代码中通过在块中添加打印或测试返回值来确认它。

在类似Unix的系统中

foo
echo $?

应该回显0

在Windows系统下的CMD.exe Windows

foo.exe
if errorlevel 1 echo "Catch block"

不应该输出Catch block

如果你的调试器允许你在catch块中执行指令…它不符合c++ 11 !

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

c++规范规定:

function-try-block将handler-seq与(如果存在)和复合语句。在执行复合语句或for期间引发的异常构造函数和析构函数,在初始化或分别销毁类的子对象,转移控件到函数尝试块中的处理程序的方法与在执行尝试块传输控制期间抛出的异常给其他处理程序。

在构造函数或任何其他函数中,try块的用法/行为没有特殊的用例。