Obfuscated C++

Last Month's Obfuscated C++
Last month we asked you to suggest a declaration or definition that will allow the following code fragment to compile and print "Success":


//What declaration of x?
if (x == &x) cout < "success\n";="">
Declaring x as something like an int* won't work, because &x will always have a different type than x. Comparison of two different pointer types for equality is not legal without casting one pointer to the type of the other (preferably by using reinterpret_cast). The solution to this puzzle can be found in the treatment of function names in section 4.3 of the ISO C++ standard:

"An lvalue of function type T can be converted to an rvalue of type 'pointer to T'. The result is a pointer to the function."
The practical effect of this is that the unqualified name of a function-without any parentheses or arguments-can be used as a synonym for its address. This means that the expressions x and &x are both legal rvalues, and are in fact synonyms, if x is the name of a function:


void x();
if (x == &x) cout < "success\n";="">

This Month's Obfuscated C++
This month we abuse exceptions. Explain the semantics of function f in the following code:


static void
g(unsigned long x)  {
    if (!x) throw 0;
    if (x&1) {
        try {g(x>>1);} catch (int x) {
            throw x+1;
        }
    }
    g(x>>1);
}

int
f(unsigned long l) {
    try {
        g(l);
    } catch (int l) {
        return l;
    }
    return 6;
}

Rob Murray is Director of Operations at the Irvine office of Nuforia, an object-oriented software consulting company based in Houston, TX. He has taught C++ at technical conferences since 1987 and is the author of C++ Strategies and Tactics. He was the founding editor of C++ Report and may be contacted at [email protected].