File: whyZMthrowRethrows.txt

package info (click to toggle)
clhep 2.1.4.1%2Bdfsg-1.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 10,012 kB
  • sloc: cpp: 50,094; sh: 6,694; makefile: 2,694; perl: 28
file content (43 lines) | stat: -rwxr-xr-x 1,846 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
When exceptions are enabled, the ZMthrow macro looks like:

#define ZMthrow(userExcept)                                             \
do { 									\
  try { throw userExcept; }                                             \
  catch ( const ZMexception & x )  {                                    \
    if ( ZMthrow_( x, __LINE__, __FILE__ ) == ZMexThrowIt ) {           \
      throw;                                                            \
    }                                                                   \
  }                                                                     \
} while (false)             

Why do we have to do that apparently convoluted try/catch block.  After all,
we know the try part will throw... why not just do:

#define ZMthrow(userExcept)                                             \
do { 									\
  if ( ZMthrow_( x, __LINE__, __FILE__ ) == ZMexThrowIt ) {             \
      throw x;                                                          \
  }                                                                     \
} while (false)             

Well, consider how ZMthrow is typically used:

ZMthrow (ZMexBadThing("explanatory text"));

The simpler code would expand this to 

do { 									
  if ( ZMthrow_( ZMexBadThing("explanatory text"), __LINE__, __FILE__ ) 
					== ZMexThrowIt ) {             
      throw ZMexBadThing("explanatory text");
  }                                                                    
} while (false)             

Notice that the exception object is constructed twice; any side effects of that
construction would occur twice.  The semantics of throw x, on the other hand,
are that x is not constructed an extra time.

The macro used achievs this:  The x reference is passed to ZMthrow but that
does not require construction, and the re-throw also does not.