--- 00TODO 2002/03/07 21:30:09 1.3
+++ 00TODO 2002/03/30 18:55:28 1.4
@@ -1,90 +0,0 @@
-
-**** IMPROVE DOCUMENTATION ****
-
-/* BAD EXAMPLE */
-try {
- char *cp1, *cp2, cp3;
-
- cp1 = mallocex(SMALLAMOUNT);
- globalcontext->first = cp1;
- cp2 = mallocex(TOOBIG);
- cp3 = mallocex(SMALLAMOUNT);
-
- strcpy(cp1, "foo"); strcpy(cp2, "bar");
-}
-clean {
- if (cp3 != NULL) free(cp3);
- if (cp2 != NULL) free(cp2);
- if (cp1 != NULL) free(cp1);
-}
-catch(ex) {
- printf("cp3=%s", cp3);
- rethrow;
-}
-
-The code above shows some pitfalls and contains many errors.
-
-01) variable scope
-
-Variables which are used in the "clean" or "catch" blocks must be declared
-before "try", otherwise they only exists inside the "try" block. In the
-example above, cp1-3 are automatic variables and only exist in the "try"
-block, the "clean" and "catch" blocks don't know anything about them.
-
-02) variable initialization
-
-Variables which are used in the "clean" or "catch" blocks must be initialized
-before the point of the first possible "throw" is reached. In the example
-above, "clean" would have trouble using cp3 when mallocex() throws a exception
-when allocating a TOOBIG buffer.
-
-03) volatile variables
-
-Variables which are used in the "clean" or "catch" blocks must be declared
-volatile, otherwise they might contain outdated information when "throw" does
-the longjmp(). When using a "free if unset" mechanism like the example does in
-the "clean" block, the variables must be initialized (see 02) *and* remain
-valid upon use.
-
-04) clean before catch
-
-The "clean" block is evaluated before "catch", so resources being cleaned up
-must no longer be used in the "catch" block. The example above would have
-trouble referencing the character strings in the printf() statement because
-these have been free()d before.
-
-05) variable uninitialization
-
-When resources are passed away and out of the scope of the "try/clean/catch"
-construct and the variables were initialized for using a "free if unset"
-mechanism then they must be uninitialized after being passed away. The
-example above would free() cp1 in the "clean" block when mallocex() throws a
-exception when allocating a TOOBIG buffer. The globalcontext->first pointer
-hence becomes invalid.
-
-/* GOOD EXAMPLE */ | /* ALTERNATE *05* GOOD EXAMPLE */
-{ /*01*/ | { /*01*/
- volatile /*03*/ char *cp1 = NULL /*02*/; | volatile /*03*/ char *cp1 = NULL /*02*/;
- volatile /*03*/ char *cp2 = NULL /*02*/; | volatile /*03*/ char *cp2 = NULL /*02*/;
- volatile /*03*/ char *cp3 = NULL /*02*/; | volatile /*03*/ char *cp3 = NULL /*02*/;
- try { | try {
- cp1 = mallocex(SMALLAMOUNT); | cp1 = mallocex(SMALLAMOUNT);
- globalcontext->first = cp1; | globalcontext->first = cp1;
- cp1 = NULL /*05 give away*/; | /*05 keep responsibility*/
- cp2 = mallocex(TOOBIG); | cp2 = mallocex(TOOBIG);
- cp3 = mallocex(SMALLAMOUNT); | cp3 = mallocex(SMALLAMOUNT);
- |
- strcpy(cp1, "foo"); strcpy(cp2, "bar"); | strcpy(cp1, "foo"); strcpy(cp2, "bar");
- } | }
- clean { | clean {
- /*04*/ printf("cp3=%s", cp3 == NULL /*02*/ ? "" : cp3); | /*04*/ printf("cp3=%s", cp3 == NULL /*02*/ ? "" : cp3);
- if (cp3 != NULL) free(cp3); | if (cp3 != NULL) free(cp3);
- if (cp2 != NULL) free(cp2); | if (cp2 != NULL) free(cp2);
- /*05 cp1 was given away */ | if (cp1 != NULL) free(cp1);
- } | }
- catch(ex) { | catch(ex) {
- /*05 global context untouched */ | globalcontext->first = NULL;
- rethrow; } | rethrow;
- } | }
-} | }
-
|