|
Prev: a compiler error in template function default argument value
Next: FRUCTOSE unit test framework status change and article correction
From: Vidar Hasfjord on 10 Apr 2008 06:22 Hi, I'm in the process of redesigning a library for handling traditional error values in C and legacy C++ code. I would very much appreciate comments on the merits and possible implementation problems with the approach outlined below. * Rationale and overview Error values without exception handling breaks composability of expressions. For example, the expression (f(x) + g(y)) must be broken up into statements that check the return value of each call. Error-value-to-exception translation wrappers solve this, but they are often verbose (see Enforcements by Alexandrescu/Marginean, Dr. Dobb's). Also, such wrappers often combine the detection and translation of an error value with handling and reporting it (e.g. passing along error messages). The proposed idiom is a lighter "footnote" approach in which error detection and translation are treated orthogonal to handling and reporting. Simply, operator % is used as an error value filter. For example: int r = E%Foo (E%Bar (a) + b); Here "E%Foo" reads as "Error-checked Foo", where E is an instance of an error checker and Foo is a function, method or functor returning some error code. E may have the following declaration elsewhere: ErrorTranslation::NotNegativeChecker E; Textually E functions similarly to a footnote in ordinary text. It says "look up E to find out more about what's going on here". * Details For detecting error codes in expressions without adding verbose wrapping a binary operator with high precedent is used; % rank at the top. Unfortunately there are unary operators of higher precedent and binary operators of same precedent. This would normally require the uses of parenthesis to specify the correct meaning. For example: E%Foo (a) * (E%Bar (b)) But proxies can be used circumvent the normal evaluation order, hence giving the illusion that E% is binding tighter than surrounding operators. E%Foo (a) * E%Bar (b) // same results as above Multiplication and division are the only binary operators of equal precedent to %. An expression (E%f(x) * E%g(y)) is evaluated as (((E% (f(x))) * E) % (g(y))) where the expression ((...) * E) returns a proxy object. The proxy object carries the value (...) and the multiplication forward through to the next check and applies the multiplication after checking. For unary operators of higher precedent, such as negation, (-f(x)) turns into (-E%f(x)) which is evaluated ((-E) % (f(x))). The expression (-E) returns a proxy object. The proxy carries the negation forward to the next check and applies it after checking. Proxies compose; e.g. a negation applied to a proxy returns a new proxy object that includes the negation. Undesirable applications, such as assignment and copying, of checkers and proxies are prohibited. Any comments appreciated. Regards, Vidar Hasfjord -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |