Friday, October 10, 2008

c++: template template parameters

Template template parameter allows to pass not complete template as a template parameter. Sounds like tongue twister. I hope an example below should demonstrate the usage of template template parameter

#include <vector>
template<typename T, template<typename T> class V>
class C
{
   V<T> v;
};
int main(int argc, char **argv)
{
   C<int,std::vector> c;
   return 0;
}

Thursday, October 9, 2008

css: absolute position

I do not do a lot of markup these days, but an article I read recently opened my eyes on the light side of absolute position of the elements.
If you place an element with absolute position into a box with relative position then child's position will be absolute relatively to the parent, it won't be removed from the document.

This one should be on the right of the box with red border.

c++: RVO and NRVO

RVO is stands for "return value optimization" and NRVO for "named return value optimization".
What does all this staff mean?

Typically, when a function returns an instance of an object, a temporary object is created and copied to the target object via the copy constructor.

RVO is a simple way of optimization when compiler doesn't create temporary when you return anonymous instance of class/structure/etc. from the function.

class C
{
    public:
        C() 
        {
            std::cout << "Constructor of C." << std::endl;
        }
        C(const C &)
        {
            std::cout << "Copy-constructor of C." << std::endl;
        }
};

C func()
{
    return C();
}

int main(int argc, char **argv)
{
    C c = func();

    return 0;
}
The output should be
Constructor of C.
Here compiler do not make a copy of C instance on return. This is a great optimization since construction of the object takes time. The implementation depends on compiler but in general compiler extends function with one parameter - reference/pointer to the object where programmer wants to store the return value and actually stores return value exact into this parameter.
It may look like
C func(C &__hidden__)
{
    __hidden__ = C();
    return;
}
NRVO is more complex. Say you have
class C
{
    public:
        C()
        {
            std::cout << "Constructor of C." << std::endl;
        }
        C(const C &c) 
        {
            std::cout << "Copy-constructor of C." << std::endl;
        }
};

C func()
{
    C c;
    return c;
}

int main(int argc, char **argv)
{
    C c = func();

    return 0;
}
Here compiler should deal with named object c. With NRVO temporary object on return shouldn't be created. The pseudocode of
C func()
{
    C c;
    c.method();
    c.member = 10;
    return c;
}
might look like
C func(C &__hidden__)
{
    __hidden__ = C();
    __hidden__.method();
    __hidden__.member = 10;
    return;
}
In both cases temporary object is not created for copying(copy-constructor is not invoked) from the function to the outside object.

When this may not work?
Situation I known when these optimizations won't work when function have different return paths with different named objects.

Wednesday, October 8, 2008

c++: inheritance from "template" class and dependance on template parameter

You may say it's quite weird that you are unable to access members of base class which depends on template parameter.

template<typename T>
class A
{
    public:
        T member;
};

template<typename T>
class B: public A<T>
{
    public:
        B();
};

template<typename T>
<T>::B()
{
    T t;
    member = t;
}
This code will raise an error that 'member' has not been found. An error occurs because of the interactions taking place in the c++ lookup rules. It comes down to that something is dependent upon some "<T>". Not that T depends upon say a typedef, but it depends upon a template parameter. In particular the use of A<T> depends upon the template parameter T, therefore the use of this base's members need to follow the rules of dependent name lookup, and hence are not directly allowed in the code above as written. To make this code work you may
  • Qualify the name with this->
    this->member = t;
  • Qualify the name with A<T>::
    A<T>::member = t;
  • Use a 'using' directive in the class template
    template<typename T>
    class A
    {
        public:
            T member;
    };
    
    template<typename T>
    class B: public A<T>
    {
        using A<T>::member;
        public:
            B();
    };
    
    template<typename T>
    B<T>::B()
    {
        T t;
        member = t;
    }
There is not everything clear with methods that depend on own template parameter.
template<typename T>
class A
{
    public:
        template<typename U>
        void func();
};

template<typename T>
template<typename U>
void
A<T>::func()
{
}

template<typename T>
class B: public A<T>
{
    public:
        B();
};

template<typename T>
B<T>::B()
{
    A<T>::func<int>();
    this->func<int>();
}
You can't write
this->member = t;
nor
A<T>::member = t;
The compiler assumes that the < is a less-than operator. In order for the compiler to recognize the function template call, you must add the template quantifier.
template<typename T>
B<T>::B()
{
    A<T>::template func<int>();
    this->template func<int>();
}
Some compilers(or their versions) don't actually parse the template until the instantiation. Those may successfully compile the code w/o specifying 'template' keyword. Without knowing the instantiation type, it can't know what 'func' refers to. In order to parse correctly, however, the compiler must know which symbols name types, and which name templates. 'template' keyword helps compiler to get that A<T>::func<int> is a template.

Monday, October 6, 2008

c++: function try-catch block

There is no hidden features in c++. Everything you can find in specification.
Somebody from Somewhere
There is an interesting feature in c++ - a function try-catch block. You can replace function body with try-catch block.
void function()
try
{
        //do smth
}
catch(...)
{
        //handle exception
}
This is almost similar to
void function()
{
        try
        {
                //do smth
        }
        catch(...)
        {
                //handle exception
        }
}
Quick notes:
  • the scope and lifetime of the parameters of a function or constructor extend into the function try-catch blocks
  • A function try-catch block on main() does not catch exceptions thrown in destructors of objects with static storage duration. In code below catch won't be called
    class A
    {
            public:
                    ~A()
                    {
                            throw "Exception in ~A";
                    }
    };
    
    int main(int argc, char **argv)
    try
    {
            static A a;
    }
    catch(const char *e)
    {
            std::cout << e << std::endl;
    }
    
  • A function try-catch block on main() does not catch exceptions thrown in constructors/destructors of namespace/global namespace scope objects. In code below catch won't be called
    namespace N
    {
            class A
            {
                    public:
                            A()
                            {
                                    throw "Exception in A";
                            }
            };
    
            A a;
    }
    
    int main(int argc, char **argv)
    try
    {
    }
    catch(const char *e)
    {
            std::cout << e << std::endl;
    }
  • The run time will rethrow an exception at the end of a function try-catch block's handler of a constructor or destructor. All other functions will return once they have reached the end of their function try block's handler
    class A
    {
            public:
                    A()
                    try
                    {
                            throw "Exception in A";
                    }
                    catch(const char *e)
                    {
                            std::cout << "In A: " << e << std::endl;
                    }
    };
    
    int main(int argc, char **argv)
    try
    {
            A a;
    }
    catch(const char *e)
    {
            std::cout << "In main: " << e << std::endl;
    }
    
    The output
    In A: Exception in A
    In main: Exception in A
    int function()
    try
    {
            throw "Exception in function";
    }
    catch(const char *e)
    {
            std::cout << "In function: " << e << std::endl;
    
            return 1;
    }
    
    int main(int argc, char **argv)
    try
    {
            std::cout << function() << std::endl;
    }
    catch(const char *e)
    {
            std::cout << "In main: " << e << std::endl;
    }
    
    The output
    In function: Exception in function
    1
    

Sunday, October 5, 2008

json: comments

I recently read some interesting observation that JSON format doesn't declare the comment strings. Though, for example, XML declares comment strings. The delusion here is that JSON is a data-interchange format, not a language. Yes, programming languages define format of comments. At least all languages I know have comments. But JSON is _not_a_language_. And XML is a language, not a format. This is my consideration. JSON is for machine-to-machine interchange. Machines ignore comments. Anyway you can reserve some part of message for comment:

{
    'comment': '',
}

Friday, October 3, 2008

perl: another way to dereference

When you have structures that have nested arrays or hashes which you want to dereference on the fly w/o using extra variable to store reference you can use special syntax:

%{reference_to_hash} and @{reference_to_array}
Next piece of code shows the common usage
$struct = [1, 2, 3, {a=>1, b=>2, c=>[1,2]}];

%hash = %{$struct->[3]};

@array = @{$struct->[3]->{c}};
This is useful when you want to work with structures but not with their references
push @{$struct->[3]->{c}}, (3, 4);

Thursday, October 2, 2008

perl: arrays and hashes

This is mostly a reminder for me than an article for everybody as I haven't touched perl for ages.

Small reference on arrays and hashes in perl.

Arrays

Declaration

@array = (1, '1', (2));
@array = (1..20);# by range
Access to array members with index
$array[0];
Define reference to array
$array = \@array; #reference to another array
$array = [1, 3, 5, 7, 9]; #reference to anonymous array
$array = [ @array ]; #reference to anonymous copy
@$array = (2, 4, 6, 8, 10); #implicit reference to anonymous array
To deference reference to array put @ or $ before $
@array = @$array;
@array = $$array;
Access to members of array by reference with index
$array->[0];# using -> operator
@$array[0];# dereferencing
$$array[0];# dereferencing
Size of the array
$#array;# [note: size of an empty array is -1, so $#array is a number of elements - 1]
Here is a tricks to remove all elements from an array, add an element to array
$#array = -1;
$c[++$#c] = 'value';
Take a slice of an array
@array[0..2];# first, second and third elements
@array[0,2];# first and third elements
Hashes

Declaration
%hash = ('key0', 'value0', 'key1', 'value1');# amount of elements must be even
%hash = ('key0' => 'value0', 'key1' => 'value1');
Access to hash members with key
$hash{'key0'};
Define reference to hash
$hash = \%hash; #reference to another hash
$hash = {1 => 3, 5 => 7}; #reference to anonymous hash
$hash = {1, 3, 5, 7}; #reference to anonymous hash; amount of elements must be even
$hash = [ %hash ]; #reference to anonymous copy
%$hash = (2, 4, 6, 8); #implicit reference to anonymous hash; amount of elements must be even
%$hash = (2 => 4, 6 => 8); #implicit reference to anonymous hash
To deference reference to hash put % or $ before $
%hash = %$hash;
%hash = $$hash;
Access to members of hash by reference with key
$hash->{'key0'};# using -> operator
%$hash[0];# dereferencing
$$hash[0];# dereferencing
Size of the hash
scalar keys(%hash)
Take a slice of a hash
@hash{'key0','key1'};
@hash{@keys};

c++: separate members from their classes

In my post c++: separate methods from their classes I described how to call class method by reference. The similar staff you can do with class members. Assume you have a collection of class instances and you want to print the values of some members from them. Again you can define two lists - list of class instances and list of pointers to class members. Later you can iterate through these list to touch members of the classes.

#include <iostream>
#include <list>

class A
{
    public:
        int m0; 
        int m1; 
};

template<typename T>
void
print(const T &a, 
    int T::*p)
{
    std::cout << a.*p << std::endl;
}

int main(int argc, char **argv)
{
    std::list<A> ls;
    std::list<int A::*> lsm;

    int A::*p0 = &A::m0;

    lsm.push_back(p0);
    lsm.push_back(&A::m1);

    A a0, a1; 
    a0.*p0 = 0;
    a0.m1 = 1;
    a1.m0 = 2;
    a1.m1 = 3;
    
    ls.push_back(a0);
    ls.push_back(a1);
    
    for (std::list<A>::iterator i = ls.begin();i!=ls.end();++i)
        for (std::list<int A::*>::iterator j = lsm.begin();j!=lsm.end();++j)
            print(*i, *j);

    return 0;
}
With this piece of code you will get
0
1
2
3
This method to access class members can be combined with class methods references to achieve more power.

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.