Con*_*tor 26 c++ program-entry-point language-lawyer noexcept c++17
以下代码在C++中是否有效?
int main() noexcept
{
}
Run Code Online (Sandbox Code Playgroud)
既铛++ 3.8.0和克++ 7.2.0 编译它细(与-std=c++14 -O0 -Wall -Wextra -Werror -pedantic-errors
编译标志).
是否允许在函数规范中使用复杂条件(例如包括noexcept
运算符)?noexcept
main
那么C++ 17呢?据我所知,noexcept
说明符成为本标准修订版中函数类型的一部分.
Bia*_*sta 20
标准[ [basic.start.main] ]指定main
函数的以下约束:
实施应允许两者:
- 返回int和的函数()
- 返回int的函数(int,指向char的指针)
此外:
将main定义为已删除或将main声明为内联,静态或constexpr的程序是不正确的.
在实践中,没有关于noexcept
限定符的规范main
.另一方面,noexcept
允许作为任何函数的说明符.这将意味着main noexcept
是没有 形成不良.
noexcept
?由于标准noexcept
对于main
我们已经看到的函数不是非常明确,我们可以尝试扣除一些行为并检查实现.
从这里:
每当抛出异常并且搜索处理程序遇到非抛出函数的最外层时,就会调用函数std :: terminate.
虽然是例外的一般规则,从这里:
如果抛出一个异常,并没有被捕获,包括逃脱的std ::线程的初始功能,主要功能,以及任何静态或本地线程对象的构造函数和析构函数的异常,那么标准::终止被调用.它是实现定义的,是否对未捕获的异常进行任何堆栈展开.
这意味着throw
from main
函数总是生成一个std::terminate
调用.无论noexcept
规格如何main
.
确实,以下代码:
int main(int argc, char* argvp[]) {
throw 1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
和
int main(int argc, char* argvp[]) noexcept {
throw 1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
将生成相同的输出组件.例如在GCC中:
main:
movl $4, %edi
subq $8, %rsp
call __cxa_allocate_exception
xorl %edx, %edx
movl $1, (%rax)
movl typeinfo for int, %esi
movq %rax, %rdi
call __cxa_throw
Run Code Online (Sandbox Code Playgroud)
这意味着它将被解析为一个调用,std::terminate
因为无论noexcept
规范如何,堆栈帧在"主级别"都是空的.
的类型的main
在 int main() noexcept;
是"的函数()
返回int
在C++ 14和"" noexcept
的函数()
返回int
在C++ 17".
前者显然需要[basic.start.main]支持.后者不是.
这看起来像C++ 17中的缺陷.
归档时间: |
|
查看次数: |
925 次 |
最近记录: |