Consider the following code snippet with exceptions. Note that the main function calls foo in the nested try block. void foo () { try { throw new Exception1(); print ("A"); } throw new Exception2(); print ("B"); catch (Exception e) { print "handler1"; } print ("C"); throw new Exception2 (); void main() { try { try { foo (); print ("D"); } catch (Exception1 e1) { print "handler2"; print ("E"); catch (Exception2 e2) { print "handler3"; }
b) Instead of the “replacement” semantics of exception handling used in modern languages
(i.e., the semantics introduced in lecture), a very early design of exception handling introduced
in the PL/I language uses a “binding” semantics. In particular, the design dynamically tracks a
sequence of “catch” blocks that are currently active; a catch block is active whenever the corre-
sponding try block is active. Moreover, whenever an exception is thrown, the sequence of active
“catch” blocks will be traversed (in a first-in-last-out manner) to find a matching handler. Fur-
thermore, execution will resume at the statement following the one that throws exception, rather
than the next statement after the matching “catch” block as we have seen in the “replacement”
semantics. What will be the output of the following program if the language uses the “binding” semantics?
Briefly justify your answer
Trending now
This is a popular solution!
Step by step
Solved in 3 steps