Is it something like unsuccessful initialization of variables of length and static in a block area? Underspecified?

After answering this question and not finding a satisfactory answer in the standard article, I began to wonder. The standard states the following wrt initialization of the specified variables:

§6.7 [stmt.dcl] p4

[...] Otherwise, such a variable is initialized when the first control passes through its declaration; such a variable is considered initialized after completion of its initialization . If initialization is completed by throwing an exception, initialization is not completed, so it will be checked again when the next control enters the declaration.

There is no mention of what could lead to a repeated attempt to initialize if it does not work otherwise than throw an exception ( longjmp() , thead exit, signals, to name a few).

Have I missed anything in the standard? I looked through the initialization articles, declarations and exceptions over and over again and even consulted the CWG content defects table with a quick search for “static” ones, but could not find anything related.

Is this a failure (and as such a defect) in the standard?

+6
source share
2 answers

The C ++ specification can only define things that are contained in the C ++ specification. Remember: the C ++ specification defines the behavior of the virtual machine that it defines. And if he does not determine that something can happen, he, of course, does not determine the behavior of C ++ around what might happen that he does not say.

According to the C ++ specification, a stream can exit in exactly three ways: returning from its main function, throwing an exception through its main function, and calling a direct process (like using std::terminate or similar functions). In short, a C ++ stream 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, everything that causes this thing that C ++ talks about cannot be, by definition, undefined. I think this would not even be “undefined behavior”; it would be in that foggy space in which there would be a thread before C ++ 11 really established how the threads interact.

The same goes for “signals,” no matter what it is. The C ++ specification does not say that this can lead to a function exit. There will be dragons.

As for longjmp , that is covered by the behavior of longjmp . When you use longjmp to exit a function, this function never ends, as if you were using throw and catch . And in C ++, an object is built only after the completion of its constructor. Therefore, the initialization of the object was never completed, and it was not initialized.

I don't have the ISO C specification (which references C ++ for longjmp behavior), but C ++ 11 strongly suggests you equate throw / catch with longjmp / setjmp if you get undefined behavior:

 §18.10 [support.runtime] p4: 

The functional signature longjmp (jmp_buf jbuf, int val) has more limited behavior in this International Standard. The pair of setjmp / longjmp codes has undefined behavior if replacing setjmp and longjmp with catch and throw will cause any non-trivial destructors for any automatic objects.

Therefore, I do not think this is unproven. It may not be pretty and neat, but all the parts are there.

+2
source

Just because one specific case is mentioned in the text does not mean that others will be different. If there are other ways to prevent initialization from completing, the implementation should try again at the next execution.

I think Nicole's answer is basically correct, but a non-trivial constructor does not imply a non-trivial destructor. longjmp can therefore interrupt initialization in such a way that it needs to be repeated. This is only difficult in a multi-threaded environment where a mutex is required to prevent a race condition between threads that will be the first to initialize. The mutex phantom object requires a nontrivial destructor, even if the initialized object does not have one. The likely result is a deadlock. This is probably good stuff for DR.

0
source

Source: https://habr.com/ru/post/907186/


All Articles