Surprisingly, I can't find an answer to that by googling and searching SO (there are lots of similar questions on SO but related to other languages).
I suspect that the answer is no
. If so, there is an obvious inconvenience, e.g.
try
{
std::string fname = constructFileName(); // can throw MyException
ofstream f;
f.exceptions(ofstream::failbit | ofstream::badbit);
f.open(fname.c_str());
// ...
}
catch (ofstream::failure &e)
{
cout << "opening file " << fname << " failed\n"; // fname is not in the scope
}
catch (MyException &e)
{
cout << "constructing file name failed\n";
}
If my assumption is correct, how do you deal with this? By moving the std::string fname;
out of try
, I guess?
I understand that a scope is defined by a {}
block, but this seems as a reasonable case for, hmm, exception. Is the reason for that that objects can be not fully constructed if an exception is thrown?
Variables declared within the try/catch block are not in scope in the containing block, for the same reason that all other variable declarations are local to the scope in which they occur: That's how the specification defines it. :-) (More below, including a reply to your comment.)
The built-in try function does not create its own scope. Modules, classes, and functions create scope.
Variables in try block So, if you declare a variable in try block, (for that matter in any block) it will be local to that particular block, the life time of the variable expires after the execution of the block. Therefore, you cannot access any variable declared in a block, outside it.
You can nest one or more try statements. If an inner try statement does not have a catch -block, the enclosing try statement's catch -block is used instead. You can also use the try statement to handle JavaScript exceptions. See the JavaScript Guide for more information on JavaScript exceptions.
Does
catch
block share the scope of thetry
block?
No.
How do you deal with this? By moving the
std::string fname;
out oftry
, I guess?
Yes.
I understand that a scope is defined by a
{}
block, but this seems as a reasonable case for, hmm, exception. Is the reason for that that objects can be not fully constructed if an exception is thrown?
The last thing C++ needs is more complex rules and exceptions to rules. :-)
There's an obvious reason: you cannot trust the state of the objects that were created inside the try block. The code there got interrupted by the exception, their constructors might not even have run yet.
While James' post correctly answers your questions, it doesn't supply the usual workaround: swap
. Assuming constructFileName()
returns std::string
and not char const*
, the following is idiomatic:
std::string fname;
try
{
constructFileName().swap(fname); // can throw MyException
std::ofstream f;
f.exceptions(std::ios_base::failbit | std::ios_base::badbit);
f.open(fname.c_str());
// ...
}
catch (std::ios_base::failure &e)
{
std::cout << "opening file " << fname << " failed\n";
}
catch (MyException &e)
{
std::cout << "constructing file name failed\n";
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With