I came across this syntax recently for try-catch
for function.
struct A { int a; A (int i) : a(i) // normal syntax { try {} catch(...) {} } A () // something different try : a(0) {} catch(...) {} void foo () // normal function try {} catch(...) {} };
Both syntax are valid. Is there any technical difference between these syntax apart from coding style ? Is one of the syntax superior to other by any aspect ?
In 'try-catch' the codes to handle the exceptions and what exception to be handled, that are easily readable. In 'if-else', we have one else block corresponding to one if block. Or we need to define another condition with command 'else if'. In 'try-catch' we don't have to define each 'try' block with a 'catch' block.
Note that you cannot use TRY... CATCH blocks inside T-SQL UDFs. If you have to capture errors that occur inside a UDF, you can do that in the calling procedure or code.
Try-catch block is used to handle the exception. In a try block, we write the code which may throw an exception and in catch block we write code to handle that exception. Throw keyword is used to explicitly throw an exception. Generally, throw keyword is used to throw user defined exceptions.
Try/catch is used when an Exception can be thrown from the code, and you catch it in the catch-clause, which is an object oriented way to handle errors. You can't catch Exceptions with if/else blocks - they share nothing with try/catch.
The First Syntax:
The scope of the try block starts after the Member Initialization list has been completed, So any exception thrown during Member Initialization will not be caught by this try-catch block.
The second syntax:
It ensures that if an exception gets thrown during Member Initialization list then you are able to catch the exception.
The Third Syntax:
It ensures that any exception thrown from betwen the starting brace of the try block inside the function body gets caught appropriately, It would mean any exception caused during the argument passing(if any can occur) will not be caught in this try-catch block.
So yes they are disinctly different in what functionality they provide.
EDIT:
Some guidelines to be considered while using the second syntax(function-try-block) in constructors & destructors:
As per the C++ Standard,
If the catch block does not throw (either rethrow the original exception, or throw something new), and control reaches the end of the catch block of a constructor or destructor, then the original exception is automatically rethrown.
In Simple words:
A constructor or destructor function-try-block's handler code MUST finish by emitting some exception.
Guideline 1:
Constructor function-try-block handlers have only one purpose -- to translate an exception. (And maybe to do logging or some other side effects.) They are not useful for any other purpose.
Throwing a exception from destructors is an bad idea, Take a look here to know why.
Guideline 2:
Destructor function-try-blocks have no practical use at all. There should never be anything for them to detect, and even if there were something to detect because of evil code, the handler is not very useful for doing anything about it because it can not suppress the exception.
Guideline 3:
Always clean up unmanaged resource acquisition in local try-block handlers within the constructor or destructor body, never in constructor or destructor function-try-block handlers.
For Standardese Fans:
C++ standard, clause 15.3, paragraph 15:
If a return statement appears in a handler of the function-try-block of a constructor, the program is ill-formed.
C++ standard, clause 15.3, paragraph 16:
The exception being handled is rethrown if control reaches the end of a handler of the function-try-block of a constructor or destructor. Otherwise, a function returns when control reaches the end of a handler for the function-try-block (6.6.3). Flowing off the end of a function-try-block is equivalent to a return with no value; this results in undefined behavior in a value-returning function (6.6.3).
References:
Have a look at this must read resource here for more details & explanation.
Function-try-block is useful mostly in constructors, because there is no other way of catching exceptions in initialization list. In destructors one must be careful to return in catch block, because exception will be automatically re-thrown. (And in good design destructors must not throw.) In normal functions this feature is not useful. Edit: an old but still good article: http://drdobbs.com/184401316
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