C++ 规范只能定义 C++ 规范中包含的内容。请记住:C++ 规范定义了它定义的虚拟机的行为。如果它没有定义可能发生的事情,那么它肯定不会定义 C++ 围绕它没有说会发生的事情的行为。
根据 C++ 规范,线程可以通过三种方式退出:从其主函数返回,通过其主函数抛出异常,以及直接进程退出(与std::terminate
或类似函数一样)。简而言之,C++ 线程不能以任何其他方式退出。标准 C++中没有ExitThread
函数。同样,std::thread
不能在外部或内部杀死线程。
因此,根据定义,任何导致 C++ 所说的不可能发生的事情都是未定义的。我想它甚至不会是“未定义的行为”;在 C++11 真正确定线程交互的工作方式之前,线程就在那个模糊的空间中。
“信号”也是如此,无论它们是什么。C++ 规范并没有说这些会导致函数退出。这里是龙。
至于longjmp
,那是由 的行为所涵盖的longjmp
。当您使用longjmp
退出函数时,该函数永远不会完成,就像您使用throw
and一样catch
。而在 C++ 中,对象仅在其构造函数完成时才被构造。因此对象的初始化从未完成,它是未初始化的。
我没有 ISO C 规范(C++ 引用了 的行为longjmp
),但 C++11 强烈建议您可以将throw
/catch
与longjmp
/等同起来setjmp
,只要你得到未定义的行为:
§18.10 [support.runtime] p4:
函数签名 longjmp(jmp_buf jbuf, int val) 在本国际标准中具有更多受限行为。如果将 setjmp 和 longjmp 替换为 catch 和 throw 将调用任何自动对象的任何非平凡析构函数,则 setjmp/longjmp 调用对具有未定义的行为。
所以我认为这并没有被低估。它可能没有很好和整齐地布置,但所有的部分都在那里。