Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why doesn't catch block share the scope of the try block?

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?

like image 784
davka Avatar asked Mar 29 '11 17:03

davka


People also ask

Are try catch blocks scoped?

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.)

Does try create a new scope?

The built-in try function does not create its own scope. Modules, classes, and functions create scope.

Why variables defined in try Cannot be used in catch or finally in Java?

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.

Can you nest try catch blocks JavaScript?

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.


3 Answers

Does catch block share the scope of the try block?

No.

How do you deal with this? By moving the std::string fname; out of try, 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. :-)

like image 133
James McNellis Avatar answered Oct 01 '22 04:10

James McNellis


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.

like image 20
Hans Passant Avatar answered Oct 01 '22 06:10

Hans Passant


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";
}
like image 40
ildjarn Avatar answered Oct 01 '22 06:10

ildjarn