函数try catch语法和main

时间:2011-12-06 19:09:16

标签: c++ exception-handling main language-lawyer

一个鲜为人知的,但几乎从未使用过的C ++特性给出了一个声明:

void foo();

一个可能的法律定义可能是:

void foo() try {
  throw 42;
}
catch(...) {
}

此处whole function implementation wrapped is within a try/catch pair,似乎与允许this类似。

int main()合法吗? E.g:

int main() try {
  throw 42;
}
catch(...) {
}

The rules for main,n3290§3.6.1主要讨论它应该采取什么样的论点以及它返回的内容 - 它们似乎并没有明确地禁止它,因为它们可能与其他各种奇怪的东西(例如联系)一样很想尝试。

这是否合法且定义明确?

2 个答案:

答案 0 :(得分:8)

标准不禁止在[basic.start.main]中使用它,并且在强制所有实现至少支持int main() {/*...*/ }int main(int argc, char* argv[]) {/*...*/}的同时,并不限制对这两个声明的实现( 3.6.1,第2段。

从孤立的角度来看,它至少看起来是合法的,当然这只涉及函数声明,而不是函数定义。

阅读,[except.handle]第13段陈述如下:

  

在具有静态存储的对象的析构函数中抛出异常   持久性或在命名空间范围对象的构造函数中不会被捕获   通过main()上的函数try-block。 (15.3第13段)

它具体提到放置在main()上的 function-try-block ,这强烈暗示这样的结构是合法的并且已经定义了行为。添加main()仅在其名称和返回类型中特殊的信息,并且该实现可能不会使其超载以改变任何行为,这使得它以正常方式起作用的强烈情况除非特别指出,例如在上面的引用中。换句话说,是的,它是合法且定义明确的。

我在这个答案的第一个版本中提供的博客文章实际上很好地说明了上面的blockquote给出的规则,所以我retain the link to it,尽管它没有直接讨论这个问题。 OP的问题。

关于OP的评论,您可以在 function-try-block 中发出return语句,[except.handle]可以这样说:

  

离开函数try-block的末尾相当于返回   没有价值;这会导致值返回时出现未定义的行为   功能(6.6.3)。 (15.3第15段)

如果你在main的末尾处于一个catch-block中,你就不会流过函数的主体(在这种情况下会是try-block),所以规则是在Flowover上主要自动调用return 0;不适用。您需要返回一些int(很可能是错误代码)以防止变得不确定。

答案 1 :(得分:0)

我已经尝试过,它编译,并按预期运行。一种特殊的表述,但我认为它没有违反任何规则。 为了清楚起见(对于您自己和将来的代码mantainers),您还可以将其改为:

int main() 
{
    try {
      throw 42;
    }
    catch( int /*...*/) {
    }
}