函数try catch语法和main



一个鲜为人知但几乎从未使用过的c++特性是:

void foo();

一个可能的法律定义是:

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

这里的整个函数实现包装在一个try/catch对中,这似乎类似于允许这样做。

这样做对int main()合法吗?例如:

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

main的规则,n3290§3.6.1主要讨论它应该接受什么参数以及它返回什么-它们似乎没有明确禁止它,因为它们对其他各种奇怪的事情(例如链接)可能会尝试。

是否合法且定义良好?

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

单独来看,它至少看起来是合法的,尽管这当然只与函数声明有关,而与函数定义无关。

继续阅读,[除了。]处理],第13段陈述如下:

在具有静态存储的对象的析构函数中抛出的异常不会捕获名称空间作用域对象的Duration或in构造函数通过main()上的function-try-block。(15.3帕。13)

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

我在这个答案的第一个版本中提供的博客文章实际上很好地说明了上述blockquote给出的规则,所以我将保留它的链接,即使它没有直接讨论OP的问题中的问题。

对于OP的注释,您可以在函数-try-block和[except]中发出返回语句。句柄]的意思是:

从function-try-block的末尾流出相当于返回没有价值的;这将导致值返回中的未定义行为函数(6.6.3)。(15.3帕。15)

如果你在main结尾的catch块中,你不会在函数体上流动(在这种情况下,这将是try块),所以main在流动时自动调用return 0;的规则不适用。您需要返回一些int(很可能是错误代码),以防止未定义

我已经试过了,它可以编译,并且按照预期运行。一个奇特的表述,但我不认为它违反任何规则。为了清晰起见(为了您自己和将来的代码维护者),您还可以将其重新表述为:

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

相关内容

最新更新