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 function
Function-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.