Tuesday, August 5, 2008

grep: locale

I've spent almost an hour with "grep -RIE 'class [a-z]+[A-Z]+' *h" trying to find classes which have names beginning with lowercase letter and contain capitals.
That grep command ignored case and I got classes with all lowercase letters also.
I've dug into the man pages and found the next paragraph:

Within a bracket expression, a range expression consists of two characters separated by a hyphen. It matches any single character that sorts between the two characters, inclusive, using the locale's collating sequence and character set. For example, in the default C locale, [a-d] is equivalent to [abcd]. Many locales sort characters in dictionary order, and in these locales [a-d] is typically not equivalent to [abcd]; it might be equivalent to [aBbCcDd], for example. To obtain the traditional interpretation of bracket expressions, you can use the C locale by setting the LC_ALL environment variable to the value C.
Yes, "LC_ALL=C grep -RIE 'class [a-z]+[A-Z]+' *h" worked for me but I didn't expect such behaivior with UTF-8 locale.

Googling a bit I've found some pages contain:
  • Collating symbols. These look like [.element.], where element is a collating element (i.e. a symbolic name for a multi-character string), and match the value of the collating element in the current locale. This doesn't seem to work in GNU grep.
  • On some locales it might include both the uppercase and lowercase of a given character. In the POSIX locale, this always expands to only the character given. 
So '[A-Z]'  is only A,B,C,...,Z for POSIX/C locale.

Monday, August 4, 2008

c++: overriding virtualization

This is a well known technique for me but just recently I heard it was called as 'overriding virtualization'. That's why I decided to expose how calling method from the explicitly mentioned class can override virtualization in classes. Consider you have

class A
{
    virtual void m();
};

class B : public A
{
    virtual void m();
};
When you create instance of class B, you will call B::m in all cases:
A *a = new B;
a->m();/// B::m here
So, if you want to call m from A? Easy:
A *a = new B;
a->A::m();/// A::m here
In the example above I've overridden the virtual call.

Monday, July 21, 2008

c++: property

Recently I'd touched an article about properties in python. They were implemented using special function property and looked very elegant:

class A(object):
  def __init__(self):
    self._x = None

  def get_x(self):
    return self._x

  def set_x(self, x):
    self._x = x

  x = property(get_x, set_x)

obj = A()
obj.x = 6    # set
print obj.x  # get
We don't have such option in c++. But it's quite simple to create one. Some implementation I saw were ugly indeed. They used a lot of code and wanted to call some routines in constructor. My version of property in c++:
#include <iostream>

template<typename T, 
         T(*s)(T &, const T &), 
         T(*g)(T &)>
class property
{
    public:
        
        T operator =(const T &nt)
        {
            return s(t, nt);
        }

        operator T()
        {
            return g(t);
        }

    protected:

        T t;
};

class A
{
    public:

        static int setter(int &i, const int &ni)
        {
            cout << "S" << endl;
            i = ni;

            return i;
        }

        static int getter(int &i)
        {
            cout << "G" << endl;

            return i;
        }

        property<int, setter, getter> p;
};

int main(int argc, char **argv)
{
    A a;

    a.p = 6;
    std::cout << a.p;

    return 0;
}
You have to define 2 static class methods(or just functions, doesn't matter) for setter and getter of the property. The modified version of class property may have default setter and getter:
template<typename T>
T setter(T &i, const T &ni)
{
    i = ni;

    return i;
}

template<typename T>
T getter(T &i)
{
    return i;
}

template<typename T, 
         T(*s)(T &, const T &) = setter<T>, 
         T(*g)(T &) = getter<T> >
class property
{
    public:
        
        T operator =(const T &nt)
        {
            return s(t, nt);
        }

        operator T()
        {
            return g(t);
        }

    protected:

        T t;
};
Now you can customize only one of them:
int getter(int &i)
{
    cout << "G" << endl;

    return i;
}

class A
{
    public:

        A(int a)
        {
            p = a;
        }


        property<int, setter<int>, getter> p;
};

Friday, June 27, 2008

gcc: statically linked shared library

Usually it's painful to distribute binaries of shared libraries across different linux distributions. They have different set of versions of shared libraries. For example if you have a library that uses libpq.so.5.0 to communicate with PostgreSQL you will fail to link against your library on distribution that has libpq.so.5.1. But there is no difference for you which to use: libpq.so.5.0 or libpq.so.5.1, anyway you will be able to connect to PostgreSQL and do DB related stuff. There is an option to compile a shared library with statically linked shared libraries in it. Let's try to build library that uses PostgreSQL's libpq: At first you just create objects for you library:

gcc -fPIC test.c -c
and compile shared library:
gcc test.o -o libtest.so -static-libgcc -shared -Wl,-soname=libtest.so\
-Wl,-static -lpq -lssl -lcrypt -lcrypto -lz
-static-libgcc is needed to link against libgcc statically[not all versions of gcc need that]. Shared libraries should go after -Wl,-static option. Be aware that you have to specify all shared libraries that can be involved on linking stage, otherwise they should be specified for binary that will be linked against libtest. Here I specified libpq, libssl, libcrypt, libcrypto, libz, to be linked statically. libpq also depends on krb5, but there's no static version of it in my distribution, so I'll link it to final binary. ldd output:
ldd libtest.so 
 statically linked
Now you can link your binary against libtest:
g++ usetest.cc -o usetest -L./ -ltest -lkrb5
That's all. ldd shows:
ldd usetest
 linux-gate.so.1 =>  (0xb7f37000)
 lib1.so => /tmp/work/lib1.so (0xb7c37000)
 libkrb5.so.3 => /usr/lib/libkrb5.so.3 (0xb7bad000)
 libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb7aca000)
 libm.so.6 => /lib/libm.so.6 (0xb7aa4000)
 libc.so.6 => /lib/libc.so.6 (0xb7964000)
 libk5crypto.so.3 => /usr/lib/libk5crypto.so.3 (0xb7940000)
 libcom_err.so.2 => /lib/libcom_err.so.2 (0xb793c000)
 libkrb5support.so.0 => /usr/lib/libkrb5support.so.0 (0xb7934000)
 libresolv.so.2 => /lib/libresolv.so.2 (0xb7921000)
 libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0xb7916000)
 /lib/ld-linux.so.2 (0xb7f38000)
 libdl.so.2 => /lib/libdl.so.2 (0xb7912000)
No libpq or libssl, libcrypt, libcrypto, libz. Congratulations. As far as I know, not all versions of ld support this. I succeeded with 'GNU ld version 2.17.50.0.6 20061020' and 'GNU ld (GNU Binutils) 2.18', but failed with 'GNU ld version 2.16.1'[on x86_64]

Thursday, June 26, 2008

c++: coma operator

I use coma operator all the time:

int a, b;
for (a=1,b=1;a<3;++a,++b)
    ...
Probably some other cases. By specification coma operator allows to call a sequence of instructions where one is allowed. So
true?(++a,b+=2,a+b):(a+=2,++b,a-b)
will evaluate ++a,b+=2 and return a+b. The other awesome thing with coma that it breaks rule for necessity of braces for blocks of code. Multiply instruction can be folded into one:
if (a == b)
    a=1, cout << a+b;

c++: v-methods overloaded by semantics

Let's assume you have such classes:

class A
{
 public:
  A() {cout << "A" << endl;}
  virtual void func() {cout << "A::func" << endl;}
};

class B : public A
{
 public:
  B() {cout << "B" << endl;}
  virtual void func() {cout << "B::func" << endl;}
};

class C
{
 public:
  virtual void func(A &a) {cout << "C::func" << endl; a.func();}
};

class D : public C
{
 public:
  virtual void func(B &b) {cout << "D::func" << endl; b.func();}
};
And when you have
A *a;
C *c;

a = new B;
c = new D;

c->func(*a);
This produces:
A
B
C::func
B::func
Costructors from A and B invoked, and ... method C::func invoked even c is an instance of D. Compiler doesn't know anything about method func from D and it's not overwritten in virtual table because it has different semantics, so C::func was executed. To let compiler correctly execute D::func the prototype of D::func should take a reference to A as an argument. Class D can be defined like this:
class D : public C
{
 public:
  virtual void func(A &a) {cout << "D::func" << endl; a.func();}
};
In this case the output will be
A
B
D::func
B::func

Wednesday, June 4, 2008

c++: ABC and virtual destructors

Everybody knows about ABC(Abstract Base Class). It contains pure-virtual methods. What do programmers forget to define ABCs? Virtual destructor. Yes, virtual destructor:

class A
{
    public:
        virtual void a() = 0;
};

class B : public A
{
    public:
        virtual ~B()
        {   
            cout >> "~B" >> endl;
        }   

        virtual void a() {}
};

int
main(int argc,
    char **argv)
{
    A *i = new B;

    delete i;

    return 0;
}
In this code destructor of class B will never be called. Why? Because there wasn't defined virtual destructor in A. What you can do here? You can define pure virtual destructor:
virtual ~A() = 0;
That's not the end. You have to define it's body, because linker will produce an error that ~A was not found:
class A
{
    public:
        virtual ~A() = 0;
        virtual void a() = 0;
};

A::~A(){}

class B : public A
{
    public:
        virtual ~B()
        {   
            cout >> "~B" >> endl;
        }   

        virtual void a() {}
};

int
main(int argc,
    char **argv)
{
    A *i = new B;

    delete i;

    return 0;
}
Now ~B will be successfully called! Be careful!

c++: polymorphism techniques

Usually you define a virtual class member when you want it to be overridden in derived classes:

class A
{
    public:
        virtual void a() 
        {
            cout >> "A:a" >> endl;
        }
        void b() 
        {
            a();
        }   
};

class B : public A
{
    public:
        virtual void a() 
        {
            cout >> "B:a" >> endl;
        }
};

int
main(int argc,
    char **argv)
{
    A *i = new B;
    i->b();
    i->a();

    return 0;
}
This code will always produce
B:a
B:a
because method A::a is virtual and when method b called method B::a is executed. We got what we want. But if you want to call A::a in A::b. One of the possible ways is to make A::a non-virtual. But this may break all other things you wanted from from virtual member. The other way(and the most elegant amongst the others as for me) is to explicitly specify of which class method a should be called:
class A
{
    public:
        virtual void a() 
        {
            cout >> "A:a" >> endl;
        }
        void b() 
        {
            A::a();
        }   
};

class B : public A
{
    public:
        virtual void a() 
        {
            cout >> "B:a" >> endl;
        }
};

int
main(int argc,
    char **argv)
{
    A *i = new B;
    i->b();
    i->a();

    return 0;
}
This code will always produce
A:a
B:a
A::b will always call A::a. Here we go ;)

Tuesday, May 27, 2008

c++: virtual functions in contructors

There is a limitation on virtual function calls in constructors. If you call a virtual function in the constructor of the base class that was overridden in derived class you will be surprised. The function of base class will be called:

class A
{
    public:
        A() {function();}
        virtual void function() {cout << "A" << endl;}
};

class B : public A
{
    public:
        B() {function();}
        virtual void function() {cout << "B" << endl;}
};

int
main(int argc,
    char **argv)
{

    B b;

    return 0;
}
This code produces
A
B
output. The explanation is pretty simple, when constructor of the base class is called the derived object has not been constructed. This way c++ protects us. You don't have access to the derived class object from the the base class constructor. Only when initialization of base class was had been finished virtual table is being refreshed.

Friday, May 23, 2008

c++: reuse memory for objects

It happens when you are creating and deleting objects heavily. Like this:

    for (int i=0;i<1000000;++i)
    {   
        A *a = new A;

        //do something with 'a'

        delete a;
    }
Yup, it happens and sometimes it's a best solution. If you can't use stack memory because A is pretty big and you used almost all of the stack memory before or used a recursion. But this is extremely slow. You obtain memory fragmentation and invoke memory manager to get free chunk of memory and than free it. c++ specification allows you to reuse memory:
#include <new>

int
main(int argc, char **argv)
{
    char *memory = new char[sizeof(A)];
    void *place = memory;
    
    for (int i=0;i<1000000;++i)
    {
        A *a = new(place) A;

        //do something with 'a'

        a->~A();
    }   
}
In the code sample above A in the loop is always put into the 'memory'. The executable will request for the chunk of memory once before the loop. Depending on the code this may be more than 10 times faster. While using new() developer have to call destructor explicitly and include 'new' header manually. Anyway, if you can put A in the loop into the stack, try to do it. It the fastest and the safest way:
    for (int i=0;i<1000000;++i)
    {   
        A a;

        //do something with 'a'
    }   

Thursday, May 22, 2008

c++: default initializers

In c++.03 you are unable to call explicitly one constructor within another:

class A
{
    public:
        A(int x, int y) : x(x), y(y) {}
        A(int x) { A(x, 0); }

        int x, y;
}
This will produce compilation errors. As a workaround developers usually use an initialization function that can be called within the constructor:
class A
{
    public:
        A(int x, int y) : {init(x, y);}
        A(int x) {init(x,0);}

        int x, y;

    protected:
        void init(int a, int b) {x = a; y = b;}
}
The idea I got today is to make an abstraction of class data in base struct, derive class from the struct and initialize struct data with it's constructor. This will make things clear and will allow to separate data from its manipulation:
struct A
{
        A(int x, int y) : x(x), y(y) {}

        int x, y;
};

class B : public A
{
    public:
        B() : A(0, 0) {}
        B(int x) : A(x, 0) {}
};

c++: constructor arguments

Names of constructor arguments which will initialize class members can have the same name as class members:

class A
{
    public:
        A(int x) : x(x) {} 

        int x;
};
I used to make a prefix for constructor arguments as thought compiler will produce an error message. Yeah, now source code can be cleaner. Be aware that next code won't work:
class A
{
    public:
        A(int x) {x = x;} 

        int x;
};
Here x in constructor's body is the argument of the contructor. You will have an unexpected value of A::x each time as it not initialized. As a workaround:
class A
{
    public:
        A(int x) {this->x = x;}

        int x;
};
Here x in constructor's body is argument of constructor and this->x is A::x.

Wednesday, May 7, 2008

bash: completion

Almost everybody uses bash. It's awesome with it simplicity and power. Recently I've been introduced to bash completion in conjunction with ssh. The author proposed to use bash completion to expand list of known hosts(~/.ssh/known_hosts) for ssh. He suggested to fetch the list and feed it to 'complete' built-in bash command:

complete -W "`cat ~/.ssh/known_hosts \
| cut -d ' ' -f1 | cut -d ',' -f1 | cut -d ']' -f1 \
| sed 's/\[//' | sort`" ssh
This command will provide a fixed list. If you eventually have gone to the new host the new hostname will be lost for the completion. I've made some investigation and have found out that you can provide a function for 'complete' that will be called each time the completion requested. Here is a function:
function _ssh_comp()
{
CUR="${COMP_WORDS[COMP_CWORD]}";
COMPREPLY=( $(compgen -W "$(gawk 'BEGIN {i=0}\
{split($1,nodes,",");\
gsub("([[]|[]]:?[0-9]*)","",nodes[1]);\
hosts[i++]=nodes[1]}\
END {for (j in hosts) {print hosts[j]}}' ~/.ssh/known_hosts)" -- ${CUR}) );
return 0;
}
From the bash reference:
We can read the description of COMPREPLY
An array variable from which Bash reads the possible completions generated by a shell function invoked by the programmable completion facility
We can also see how we found the current word using the array COMP_WORDS to find both the current and the previous word by looking them up
An array variable consisting of the individual words in the current command line. This variable is available only in shell functions invoked by the programmable completion facilities.
COMP_CWORD
An index into ${COMP_WORDS} of the word containing the current cursor position. This variable is available only in shell functions invoked by the programmable completion facilities
Then you should tell 'complete' to use this function:
complete -o default -F _ssh_comp ssh
I typed 'ssh 1' then pressed and here we go:
$ssh 192.168.229.1
192.168.229.128  192.168.229.130  192.168.229.132  192.168.229.134  192.168.229.137  192.168.229.140  192.168.229.145  
192.168.229.129  192.168.229.131  192.168.229.133  192.168.229.136  192.168.229.138  192.168.229.144  192.168.229.146