Вопрос

I've encountered an example (for a trivial function-try-block), from which seems to utilize one of the more obscure of aspects of C++ syntax to which (like most obscure aspects of the language) I can not seem to find documentation for.

I've searched the Google to no avail, with all searches returning (rather uselessly) only for constructor initialization (which I'm familiar with), but what I would like to know is the importance of the body: and handler: statements in this constructor block:

class foo{
    foo() try
    //initalizer list that could throw
    {
    body:
       //do stuff that could possibly throw
    } catch(std::exception &e) {
    handler:
       throw;
    }
};

The original author abruptly adds this syntax in a single example and I would like to know the implications of such linguistic constructs

Это было полезно?

Решение

The XXX: is a label. It doesn't serve any functional purpose in the code you posted. It may have been put in by the author to help them organize the code.

You can use labels with goto statements, as in goto XXX; to jump to that point in your code, although I'll leave it up to you to decide if that is a good think or now.

Другие советы

foo::foo()
try
{
body:
   //... do stuff that could possibly throw
}
catch(std::exception &e){
handler:
   throw;
}

That piece of code has two rather unusual constructs. The first is what you already pointed out and has already been explained in mjk's answer: body and handler are labels. Labels are used for gotos, and that in turn can be used for flow control (determining where the code should continue executing). Now, gotos should rarely be used, as there are very few cases where they cannot be substituted by other flow controls (if,for,while,do...) that would make it more readable. Since gotos are rarely used, labels are also rarely used.

The second interesting construct is the function-level try block:

foo::foo()
try {
} catch (std::exception const &) {
}

Note that there try catch is not inside the constructor body, but actually outside the {}. This is also a rare construct. It was designed to support catching an exception during the evaluation of the initializer list in the constructor (which in the code above is implicit). If the type has a base, or members whose constructors could throw, the constructor's body would never be evaluated and a regular try-catch would not be useful to treat that exception. The function level try block encloses also the initializer list and will catch any exception thrown during the evaluation of the different submember's constructors. It is a rarely used construct since you cannot really do much in the catch block. The exact state of what has been or has not been constructed is unknown and cannot be verified so the only possible use is to rethrow either the same exception or a different one. The syntax in a more complete example would be:

T::T() 
try
   : base1(args), base2(), member1(), member2() //...
{
   // body
} catch (exception1 const& ex1) {
   // ...
   throw; // rethrow same exception
} catch (exception2 const& ex2) {
   // ...
   throw different_exception();
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top