Harvard Business School of Echec

Aller au contenu | Aller au menu | Aller à la recherche

dimanche, 22 avril 2007

Iterate & Erase

I have discovered a nice bug in my code. I had some stuff about iterating a std::list<> and removing some elements at the same time. Like the following :

std::list<> l;

iterator it(l.begin());

while (it != l.end()) {
	if (...)
		it = l.erase(it);
	else
		++it;
}

Then i moved from std::list<> to std::set<> (ordered set). The code didn't compile as is because std::set<>::erase returns void. The STL documentation says Erasing an element from a set also does not invalidate any iterators.... OK then, no return value.

std::set<> s;

iterator it(s.begin());

while (it != s.end()) {
	if (...)
		s.erase(it);
	++it;
}

It worked nicely for a long time. But once i got a double free crash. In order to debug it, i added many print. For example {1 2 3 5 6 7} - {3} shoud have printed {1 2 5 6 7} but instead i got {1 2 2 5 6 7} or {1 5 6 7 2} !

So i read again the documentation : Erasing an element from a set also does not invalidate any iterators, except, of course, for iterators that actually point to the element that is being erased.. Bon sang !

The correct way to do it :

std::set<> s;

iterator it(s.begin())

while (it != s.end()) {
	iterator next(it);
	++next;
	if (...)
		s.erase(it);
	it = next;
}

samedi, 16 décembre 2006

Type safety

Converting system-monitor to C++ helped me to spot a lot of small errors. The most common is about enum. For example, gtk_table_attach has arguments of type GtkAttachOptions. Old code used 0 which is not a valid GtkAttachOptions but doesn't yield any warning about this, not even at runtime. Thanks to g++, i've been able to fix these errors.

Moreover, C++ makes me able to write more readable code. I'm trying to convert some C code to C++, and i just can't understand what i meant.

pretty_table->app_hash = g_hash_table_new (NULL, NULL);

pretty_table->default_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);

No type information. I had to read all the code to remember the purpose of these data. Ugly GUINT_TO_POINTER inside :) Using C++, i simply use map<string, int> which gives me type information and type safety :)

jeudi, 14 décembre 2006

I've lost 5 years of work

In the process of converting system-monitor to C++, i had to rename most of the files. I've lost complete history of the whole project :(

We'll be soon in 2007 and we're still stuck with CVS mid-80 features. Yes, i'm only 3 years older than CVS. I'm ready to move to {git,monotone,mercurial} but now it's too late to avoid damage.