I'm working through a book on C++ and in the chapter on errors it has this program (I left a couple of minor things out but it's mostly this):
int main()
try {
// our program (<- this comment is literally from the book)
return 0;
}
catch(exception& e) {
cerr << "error: " << e.what() << '\n';
return 1;
}
catch(...) {
cerr << "Unknown exception\n";
return 2;
}
This compiled but of course it did nothing so I'm still wondering about
Those that get used to the Python way of doing things tend to start seeing curly braces as unnecessary line noise that clutters code. On the other hand, 'the whitespace thing' is possibly the single biggest reason why some developers refuse to even try Python.
One-line statement Well if there is only one statement to execute after if condition then using curly braces or not doesn't make it different. Without curly braces only first statement consider in scope so statement after if condition will get executed even if there is no curly braces.
Curly braces indicates the block of statements in C programming language. The function in C has braces in its syntax. But one can put braces where logically related statements are written. A single statement in loop or if-else block need not be written within braces.
If the number of statements following the for/if is single you don't have to use curly braces. But if the number of statements is more than one, then you need to use curly braces.
If you use a try block directly instead of braces, the try block catches everything that happens in the function. This is useful in constructors so you can catch exceptions in the initialization list.
This will catch exceptions from bar's constructor:
void Foo::Foo() try : bar() {
// do something
} catch(...) {
// do something
}
This will only catch exceptions in the body:
void Foo::Foo() : bar() {
try {
// do something
} catch(...) {
// do something
}
}
1 why there isn't a set of curly braces enclosing everything after main()? ...
There is, it just has the keyword try
before the opening brace, and some catch
blocks after the end of main
.
... Are the blocks or shall I call them "catchphrases" (ha!) part of main() or not?
2 If they are functions how come there's no "int" before catch(whatever)?
3 If they're not functions, what are they?
They're keywords, not functions, and they're part of main, despite the try
coming between the int main()
definition and its {}
body. See the motivating case below for another example.
4 re catch(...), I've never seen ellipses used that way. Can I use ellipses anywhere to mean "anything"?
there are a couple of overloaded meanings of ellipsis in C++.
catch(...)
means catch anything, it's like a wildcard for the exception type (and should be the last catch if you have several)int printf(char *, ...)
means a function takes a variable argument list, which entirely disables type-checking of arguments and is easy to get wrong (but occasionally useful)template <typename... TypePack>
means a template accepts a variable type list, which is very useful for metaprogramming but completely out of scope here#define DEBUG(str, ...)
is a variadic macro, analogous to the variable-argument functionFunction-level try
/catch
blocks are a way of wrapping the whole function body in an exception handler. So, here, the main function block is inside the try { ... }
.
IIRC this was introduced specifically to allow constructors to wrap their initializer lists with a try
/catch
, to handle exceptions thrown from subobject constructors.
Eg. (motivating case)
C::C() try : Base(1), member(2)
{ ...
}
catch (...) {
// handle Base::Base or member construction failure here
}
Note that there is no other way to catch exceptions thrown from base class or member subobject constructors, because they'll always do at least default construction before your constructor body starts, even if you omit the initializer list.
That is a rarely used feature of the language. You can enclose a whole function in a try
catch block:
void f()
try
{ // function starts here
...
} // function ends here
catch (...)
{}
The feature is rarely used as it is almost never useful. In the case of a regular function, you can just have a try/catch block that covers all the code of the function, so in this case the feature would not be needed. It has limited functionality in constructors, as it allows catching exceptions on the initializer list, that cannot be enclosed in a try/catch block otherwise.
But the problem there is that there is very little that can be done in the catch block: construction failed so an exception must be thrown (the catch block can throw a different exception to what was caught, but it has to throw). At the same time, you cannot really perform any cleanup, since at the point where the exception is caught you might not know which of the elements in the initialization list threw, which means that you might not know (in the general case) which of the member objects have been constructed or not.
It's function-try block
. Yes, it's legal, but not needed in more cases. Look at this answer for explanations. What is the meaning of this syntax?
Not sure about the missing curly braces around the main function, but it looks like others answered that all ready.
As for the rest of your question, try catch blocks are not functions outside the main, and do not need an int
in front of them.
try {}
: The program will try to run anything within this block, if it fails for whatever reason, it will be caught by the catch blocks.
catch (exception) {}
: When an exception is thrown, it will be caught by a catch block with the specific Exception as its parameter, and allow for the programmer to handle that case.
catch (...) {}
: Should catch anything that makes it through the first catch block..
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