Is what constitutes a failed initialization of block-scope static or thread storage duration variables underspecified?

后端 未结 2 588
盖世英雄少女心
盖世英雄少女心 2021-02-15 23:56

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 mentione

2条回答
  •  抹茶落季
    2021-02-16 00:09

    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.

    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.

    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.

    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.

    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.

    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:
    

    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.

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

提交回复
热议问题