是什么构成块范围静态或线程存储持续时间变量的初始化失败? [英] Is what constitutes a failed initialization of block-scope static or thread storage duration variables underspecified?

查看:628
本文介绍了是什么构成块范围静态或线程存储持续时间变量的初始化失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在回答这个问题后,在标准文件中没有找到令人满意的答案,我开始怀疑。标准规定如下。初始化上述变量:

After answering this question and not finding a satisfying answer in the standard paper, I started wondering. The standard states the following w.r.t. initialization of mentioned variables:

§6.7[stmt.dcl] p4


[...]否则,这样的变量在第一次控制通过其声明时被初始化; 此类变量在初始化完成后被视为已初始化。如果初始化通过抛出异常退出,初始化不完全,因此下次控制进入声明时将再次尝试。

[...] Otherwise such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration.

没有提到什么可能会导致重试的初始化,如果它失败,除了抛出异常( longjmp(),退出,信号命名a很少)。

There is no mentioning of what might cause the initialization to be retried if it failed by anything else than throwing an exception (longjmp(), thead exit, signals to name a few).

我忽略了标准中的任何内容吗?我一遍遍地查看初始化,声明和例外条款,甚至查阅了 CWG缺陷表内容,并快速搜索静态,但找不到任何相关的内容。

Did I overlook anything in the standard? I looked through initialization, declaration and exception clauses over and over and even consulted the CWG defects table of content with a quick search for "static", but couldn't find anything related.

这是一个underspecification )在标准中?

推荐答案

C ++规范只能定义C ++规范中包含的内容。记住:C ++规范定义了它定义的虚拟机的行为。如果它没有定义可能发生的事情,它肯定不会定义C ++的行为,它不会说可以发生的事情。

The C++ specification can only define things that are contained within the C++ specification. Remember: the C++ specification defines the behavior of a virtual machine it defines. And if it doesn't define that something can happen, it certainly doesn't define the behavior of C++ around that something that it doesn't say can happen.

对于C ++规范,线程可以以三种方式退出:从它的主函数返回,通过其主函数抛出一个异常,并直接退出(如 std :: terminate 或类似的函数)。总之,C ++线程不能以任何其他方式退出。在标准C ++中没有 ExitThread 函数。类似地, std :: thread 无法在外部或内部杀死一个线程。

According to the C++ specification, a thread can exit in exactly three ways: by returning from its main function, throwing an exception through its main function, and direct process exiting (as with std::terminate or similar functions). In short, a C++ thread cannot exit in any other way. There is no ExitThread function in standard C++. Similarly, std::thread cannot kill a thread, either externally or internally.

这个C ++说不能发生的事情是,通过定义未定义。我想它甚至不会是未定义的行为;它将在那个模糊的空间中,线程是在C ++ 11之前实际上规定了线程交互如何工作。

Therefore, anything that does cause this thing that C++ says can't happen is, by definition undefined. I guess it wouldn't even be "undefined behavior"; it would be in that nebulous space that threading was in before C++11 actually laid down how thread interactions worked.

signals 。 C ++规范不说那些可以导致函数退出。这是龙。

The same goes for "signals", whatever those are. The C++ spec doesn't say that those can cause a function to exit. Here be dragons.

对于 longjmp ,这是 longjmp 。当你使用 longjmp 退出一个函数时,该函数从未完成,就像你使用 throw catch 。在C ++中,一个对象只有在其构造函数完成时才被构造。因此,对象的初始化从未完成,并且未初始化。

As for longjmp, that's covered by the behavior of longjmp. When you use longjmp to exit a function, that function never finished, just as if you used throw and catch. And in C++, an object is only constructed when its constructor has completed. Therefore the object's initialization was never completed, and it is uninitialized.

我没有ISO C规范(C ++引用的 longjmp ),但C ++ 11强烈建议您可以将 throw / catch with longjmp / setjmp ,直到获得未定义的行为:

I don't have the ISO C specification (which C++ references for the behavior of longjmp), but C++11 does strongly suggest that you can equate throw/catch with longjmp/setjmp, as far as when you get undefined behavior:

§18.10 [support.runtime] p4:


$ b b


函数签名longjmp(jmp_buf jbuf,int val)在本国际标准中的行为更受限制。 setjmp / longjmp调用对具有未定义的行为,如果用catch和throw替换setjmp和longjmp将为任何自动对象调用任何非平凡的析构函数。

The function signature longjmp(jmp_buf jbuf, int val) has more restricted behavior in this International Standard. A setjmp/longjmp call pair has undefined behavior if replacing the setjmp and longjmp by catch and throw would invoke any non-trivial destructors for any automatic objects.

所以我不认为这是underpecified。它可能不是很好,整洁地布局,但所有的作品都在那里。

So I don't think this is underspecified. It may not be nicely and neatly laid out, but all of the pieces are there.

这篇关于是什么构成块范围静态或线程存储持续时间变量的初始化失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆