Monday, September 29, 2008

c++: Koenig lookup

Koenig lookup, named after Andrew Koenig, a former AT&T researcher and programmer known for his work with C++ is also known as argument dependent lookup.
Argument dependent lookup applies to the lookup of unqualified function through the namespaces according to the types of given arguments.
Let's go through a simple example.

#include <iostream>

namespace NS1 
{
    class A
    {   
        public:
            A() {std::cout << "NS1::A::A";}
    };  

    template<typename T>
    void f(T a)
    {   
    }   
}

int main(int argc, char **argv)
{
    NS1::A v;
    f(v);

    return 0;
}
Under normal conditions compiler will look for f in global namespace and fail as there is no such routine there. But modern compiler can be more intelligent: it can look at the arguments and exposes function from the namespace where arguments came. This will compile with modern compilers but will fail with old.

On the other hand the next piece of code might cause another kind problem.
#include <iostream>

namespace NS1 
{
    class A
    {   
        public:
            A() {std::cout << "NS1::A::A";}
    };  

    template<typename T>
    void f(T a)
    {   
    }   
}

template<typename T>
void f(T a)
{
}

int main(int argc, char **argv)
{
    NS1::A v;
    f(v);

    return 0;
}
The compilation will fail with compilers that do Koenig lookup with "call of overloaded function is ambiguous" error but will succeed with compilers that do not perform Koenig lookup. Old compilers will call function from the global namespace.

For portability the namespace should be declared explicitly.

Monday, September 15, 2008

linux: emergency reboot remote box

Once I've faced very unusual problem for me.
I started to reboot the remote box and was unable to do it, because kernel thread [pdflush] was in uninterruptible sleep.

For local machines I used to hit SysRq+b, but here it doesn't work for me.

The solution was quite simple. Send SysRq+b via /proc filesystem:

echo b > /proc/sysrq-trigger

Friday, September 12, 2008

python: tuple with one item

When you want to construct a tuple containing only one item you should write

variable = (1,)
You have to add extra coma after the item. If you forget this coma the item will be returned, not the tuple.
Weird =/

c++: exception in constructor

I wonder why people want to make all the stuff in constructor.

Constructor do not return anything, so it can't indicate that it failed to do something.

The only way is (please close your eyes here)to throw an exception(now you can open the eyes).

When you throw an exception in the constructor the destructor will not be called. Because compiler doesn't actually know whether the object had been constructed or not. So it's more safe to omit execution of destructor in this case.

So you should clean the stuff just before throwing the exception:

class A
{
    public:
        A()
        {
            do_stuff();

            if (smth_goes_wrong)
            {
                clean_the_shoes();

                throw ticket_to_hell;
            }  

            do_other_stuff();
        }  
}
Knowing that you can keep safe your code even anything else may throw an exception in your constructor:
class A
{
    public:
        A()
        {
            try
            {
                do_stuff();
            }
            catch (...)
            {
                clean_the_shoes();

                throw;
            }   

            do_other_stuff();
        }   
};
Or even better not to throw the caught exception upstairs and do not call anything that might throw an exception at all. Much better to have an init method that may fail safely and call it after the constructor had been called and you are able to safely handle any exceptions.