Reputation: 385
Please help with an example to understand below
From C++ n45277 : $15.3 - 13
If a
return
statement appears in a handler of the function-try-block of a constructor, the program is ill-formed.
does this mean using return
in constructor ??
Thanks
Upvotes: 4
Views: 764
Reputation: 596672
A function-try-block is a try
block that wraps outside the entire body of a function or constructor, rather than just a section of code inside of the body.
In the case of a constructor, it allows you to catch an exception that is thrown while initializing base classes and data members within the initialization list. If such an exception is thrown, you can catch
it and process the error as needed, but you cannot return
from the catch
block. When execution reaches the end of the catch
block, the current exception is automatically rethrown. Before the catch
is entered, any base class and data member that was successfully constructed before the initial exception was thrown has already been destructed to prevent leaks.
As the standard says:
If a
return
statement appears in a handler of the function-try-block of a constructor, the program is ill-formed.
In this case, the handler is referring to a catch
block of the try
block.
For example:
int checkValue(int value)
{
if (value == 1)
throw std::runtime_error("illegal value");
return value;
}
struct A
{
std::string str;
int value;
A(int i) try : str("hello"), value(checkValue(i))
{
// constructor body here ...
// 'return' is OK here!
}
catch (...)
{
// do something here (log the error, etc)...
// 'return' is illegal here!
}
};
Notice how the try
is before the initialization list, and the body of the constructor is inside of the try
block.
If checkValue()
throws an exception, the construction of A
is aborted, automatically destructing str
in the process.
You could accomplish the same thing without using a function-try-block:
int checkValue(int value)
{
if (value == 1)
throw std::runtime_error("illegal value");
return value;
}
struct A
{
std::string str;
int value;
A(int i)
{
try
{
str = "hello";
value = checkValue(i);
// 'return' is OK here!
}
catch (...)
{
// do something here (log the error, etc)...
// 'return' is OK here! But then the constructor
// would not be aborted...
throw;
}
}
};
Where function-try-block is commonly used is when you want to catch/log exceptions that are thrown in things that cannot be invoked inside the normal constructor body, only in the initialization list, such as base class constructors and data member constructors.
Upvotes: 3