Last year at university I was participating at course for game development on a C64 machine. Let’s get back to the 80s… Most of the time it was fun. But it was also challenging for us to develop thousands of lines of code in Assembler. Something completely different to the object oriented programming I do normally.

The game we developed is based on the well known Pong but extends it with some interesting tweaks like two paddles per player etc.

Here are the downloads:

The game should be playable on every modern C64 emulator or the real one. It was developed on vice.

In die aktuelle Linux-Version von Google Earth (5.1.3506.3999) scheint sich ein recht übler Bug, was das Verarbeiten von Tracks angeht, eingeschlichen zu haben.  Bisher hatte ich nie Probleme, GPX-Dateien von meine GPS zu Laden, doch als ich es heute zum ersten Mal mit dieser Version versucht hab, war mein Track nur eine senkrechte Linie auf der Karte. Auch eine mit GPS-Babel nach *.kml konvertierte Variante hatte dieses Problem. Was hingegen funktioniert hat, war das Erstellen, Speichern und erneute Laden eines Tracks in Google Earth. Ein Vergleich der meiner KML-Datei mit der von Google Earth selbst generierten hat einen netten Fehler aufgedeckt: Google hat wohl etwas zu viel i18n oder l10n gemacht, so dass beim Erstellen und Laden von Dateien das landestypische Dezimalzeichen (also mit deutscher Locale ein Komma) benutzt wird. Laut GPX- und KML-Spezifikation ist es natürlich totaler Müll, Koordinaten in der Form 52,xxx zu benutzen. Folgender Trick hat Google Earth dann davon überzeugt doch einen Punkt als Dezimaltrenner zu benutzen:
LANG="" googleearth
So startet Google Earth auf Englisch.

16.08.2009

Geocaching II

7.08.2009

Geocaching…

Geocaching..

Geocaching...

Geocaching...

Geocaching...

Template Programming to the Extreme… Manchmal macht es echt eine Freude den Quellcode der BGL (Boost Graph Library) zu lesen. Hier ein paar Highlights:

  1. typename T::ThereReallyIsNoMemberByThisNameInT vertices(T const&);
  1. // The graph is passed by *const* reference so that graph adaptors
  2. // (temporaries) can be passed into this function. However, the
  3. // graph is not really const since we may write to property maps
  4. // of the graph.

Spaßig sind aber auch die Compiler-Fehlermeldungen:

make all
Scanning dependencies of target imnbase
[ 7%] Building CXX object src/CMakeFiles/imnbase.dir/algorithms/DefaultAlgorithmFactory.cpp.o
[ 14%] Building CXX object src/CMakeFiles/imnbase.dir/algorithms/parallelScan/ParallelScan.cpp.o
/usr/local/include/boost/mpi/datatype.hpp: In function »ompi_datatype_t* boost::mpi::get_mpi_datatype(const T&) [with T = std::basic_string, std::allocator >]«:
/usr/local/include/boost/mpi/detail/mpi_datatype_primitive.hpp:96: instantiated from »void boost::mpi::detail::mpi_datatype_primitive::save(const T&) [with T = std::basic_string, std::allocator >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:95: instantiated from »static void boost::archive::save_access::save_primitive(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::basic_string, std::allocator >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:212: instantiated from »static void boost::archive::detail::save_non_pointer_type::save_primitive::invoke(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::basic_string, std::allocator >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:294: instantiated from »static void boost::archive::detail::save_non_pointer_type::invoke(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::basic_string, std::allocator >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:506: instantiated from »void boost::archive::save(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::basic_string, std::allocator >]«
/usr/local/include/boost/mpi/detail/ignore_skeleton_oarchive.hpp:46: instantiated from »void boost::mpi::detail::ignore_skeleton_oarchive::save_override(const T&, int) [with T = std::basic_string, std::allocator >, Archive = boost::mpi::detail::mpi_datatype_oarchive]«
/usr/local/include/boost/archive/detail/interface_oarchive.hpp:64: instantiated from »Archive& boost::archive::detail::interface_oarchive::operator<<(T&) [with T = const std::basic_string, std::allocator >, Archive = boost::mpi::detail::mpi_datatype_oarchive]«
/usr/local/include/boost/serialization/nvp.hpp:78: instantiated from »void boost::serialization::nvp::save(Archivex&, unsigned int) const [with Archivex = boost::mpi::detail::mpi_datatype_oarchive, T = const std::basic_string, std::allocator >]«
/usr/local/include/boost/serialization/access.hpp:93: instantiated from »static void boost::serialization::access::member_save(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = const boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/serialization/split_member.hpp:43: instantiated from »static void boost::serialization::detail::member_saver::invoke(Archive&, const T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/serialization/split_member.hpp:69: instantiated from »void boost::serialization::split_member(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/serialization/nvp.hpp:88: instantiated from »void boost::serialization::nvp::serialize(Archive&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = const std::basic_string, std::allocator >]«
/usr/local/include/boost/serialization/access.hpp:109: instantiated from »static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/serialization/serialization.hpp:74: instantiated from »void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/serialization/serialization.hpp:133: instantiated from »void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:220: instantiated from »static void boost::archive::detail::save_non_pointer_type::save_only::invoke(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:294: instantiated from »static void boost::archive::detail::save_non_pointer_type::invoke(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:506: instantiated from »void boost::archive::save(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/mpi/detail/ignore_skeleton_oarchive.hpp:46: instantiated from »void boost::mpi::detail::ignore_skeleton_oarchive::save_override(const T&, int) [with T = boost::serialization::nvp, std::allocator > >, Archive = boost::mpi::detail::mpi_datatype_oarchive]«
/usr/local/include/boost/archive/detail/interface_oarchive.hpp:64: instantiated from »Archive& boost::archive::detail::interface_oarchive::operator<<(T&) [with T = const boost::serialization::nvp, std::allocator > >, Archive = boost::mpi::detail::mpi_datatype_oarchive]«
/usr/local/include/boost/serialization/collections_save_imp.hpp:60: instantiated from »void boost::serialization::stl::save_collection(Archive&, const Container&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, Container = std::vector, std::allocator >, std::allocator, std::allocator > > >]«
/usr/local/include/boost/serialization/vector.hpp:53: instantiated from »void boost::serialization::save(Archive&, const std::vector&, unsigned int, mpl_::false_) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, U = std::basic_string, std::allocator >, Allocator = std::allocator, std::allocator > >]«
/usr/local/include/boost/serialization/vector.hpp:123: instantiated from »void boost::serialization::save(Archive&, const std::vector&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, U = std::basic_string, std::allocator >, Allocator = std::allocator, std::allocator > >]«
/usr/local/include/boost/serialization/split_free.hpp:45: instantiated from »static void boost::serialization::free_saver::invoke(Archive&, const T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::vector, std::allocator >, std::allocator, std::allocator > > >]«
/usr/local/include/boost/serialization/split_free.hpp:74: instantiated from »void boost::serialization::split_free(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::vector, std::allocator >, std::allocator, std::allocator > > >]«
/usr/local/include/boost/serialization/vector.hpp:147: instantiated from »void boost::serialization::serialize(Archive&, std::vector&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, U = std::basic_string, std::allocator >, Allocator = std::allocator, std::allocator > >]«
/usr/local/include/boost/serialization/serialization.hpp:133: instantiated from »void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::vector, std::allocator >, std::allocator, std::allocator > > >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:144: instantiated from »void boost::archive::detail::oserializer::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::vector, std::allocator >, std::allocator, std::allocator > > >]«
/home/languitar/workspace/iMN/src/algorithms/parallelScan/ParallelScan.cpp:128: instantiated from here
/usr/local/include/boost/mpi/datatype.hpp:184: Fehler: keine passende Funktion für Aufruf von »assertion_failed(mpl_::failed************ boost::mpi::is_mpi_datatype, std::allocator > >::************)«
/usr/local/include/boost/mpi/detail/mpi_datatype_cache.hpp: In member function »ompi_datatype_t* boost::mpi::detail::mpi_datatype_map::datatype(const T&, typename boost::disable_if, void>::type*) [with T = std::basic_string, std::allocator >]«:
/usr/local/include/boost/mpi/datatype.hpp:185: instantiated from »ompi_datatype_t* boost::mpi::get_mpi_datatype(const T&) [with T = std::basic_string, std::allocator >]«
/usr/local/include/boost/mpi/detail/mpi_datatype_primitive.hpp:96: instantiated from »void boost::mpi::detail::mpi_datatype_primitive::save(const T&) [with T = std::basic_string, std::allocator >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:95: instantiated from »static void boost::archive::save_access::save_primitive(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::basic_string, std::allocator >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:212: instantiated from »static void boost::archive::detail::save_non_pointer_type::save_primitive::invoke(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::basic_string, std::allocator >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:294: instantiated from »static void boost::archive::detail::save_non_pointer_type::invoke(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::basic_string, std::allocator >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:506: instantiated from »void boost::archive::save(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::basic_string, std::allocator >]«
/usr/local/include/boost/mpi/detail/ignore_skeleton_oarchive.hpp:46: instantiated from »void boost::mpi::detail::ignore_skeleton_oarchive::save_override(const T&, int) [with T = std::basic_string, std::allocator >, Archive = boost::mpi::detail::mpi_datatype_oarchive]«
/usr/local/include/boost/archive/detail/interface_oarchive.hpp:64: instantiated from »Archive& boost::archive::detail::interface_oarchive::operator<<(T&) [with T = const std::basic_string, std::allocator >, Archive = boost::mpi::detail::mpi_datatype_oarchive]«
/usr/local/include/boost/serialization/nvp.hpp:78: instantiated from »void boost::serialization::nvp::save(Archivex&, unsigned int) const [with Archivex = boost::mpi::detail::mpi_datatype_oarchive, T = const std::basic_string, std::allocator >]«
/usr/local/include/boost/serialization/access.hpp:93: instantiated from »static void boost::serialization::access::member_save(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = const boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/serialization/split_member.hpp:43: instantiated from »static void boost::serialization::detail::member_saver::invoke(Archive&, const T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/serialization/split_member.hpp:69: instantiated from »void boost::serialization::split_member(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/serialization/nvp.hpp:88: instantiated from »void boost::serialization::nvp::serialize(Archive&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = const std::basic_string, std::allocator >]«
/usr/local/include/boost/serialization/access.hpp:109: instantiated from »static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/serialization/serialization.hpp:74: instantiated from »void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/serialization/serialization.hpp:133: instantiated from »void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:220: instantiated from »static void boost::archive::detail::save_non_pointer_type::save_only::invoke(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:294: instantiated from »static void boost::archive::detail::save_non_pointer_type::invoke(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:506: instantiated from »void boost::archive::save(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/mpi/detail/ignore_skeleton_oarchive.hpp:46: instantiated from »void boost::mpi::detail::ignore_skeleton_oarchive::save_override(const T&, int) [with T = boost::serialization::nvp, std::allocator > >, Archive = boost::mpi::detail::mpi_datatype_oarchive]«
/usr/local/include/boost/archive/detail/interface_oarchive.hpp:64: instantiated from »Archive& boost::archive::detail::interface_oarchive::operator<<(T&) [with T = const boost::serialization::nvp, std::allocator > >, Archive = boost::mpi::detail::mpi_datatype_oarchive]«
/usr/local/include/boost/serialization/collections_save_imp.hpp:60: instantiated from »void boost::serialization::stl::save_collection(Archive&, const Container&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, Container = std::vector, std::allocator >, std::allocator, std::allocator > > >]«
/usr/local/include/boost/serialization/vector.hpp:53: instantiated from »void boost::serialization::save(Archive&, const std::vector&, unsigned int, mpl_::false_) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, U = std::basic_string, std::allocator >, Allocator = std::allocator, std::allocator > >]«
/usr/local/include/boost/serialization/vector.hpp:123: instantiated from »void boost::serialization::save(Archive&, const std::vector&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, U = std::basic_string, std::allocator >, Allocator = std::allocator, std::allocator > >]«
/usr/local/include/boost/serialization/split_free.hpp:45: instantiated from »static void boost::serialization::free_saver::invoke(Archive&, const T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::vector, std::allocator >, std::allocator, std::allocator > > >]«
/usr/local/include/boost/serialization/split_free.hpp:74: instantiated from »void boost::serialization::split_free(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::vector, std::allocator >, std::allocator, std::allocator > > >]«
/usr/local/include/boost/serialization/vector.hpp:147: instantiated from »void boost::serialization::serialize(Archive&, std::vector&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, U = std::basic_string, std::allocator >, Allocator = std::allocator, std::allocator > >]«
/usr/local/include/boost/serialization/serialization.hpp:133: instantiated from »void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::vector, std::allocator >, std::allocator, std::allocator > > >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:144: instantiated from »void boost::archive::detail::oserializer::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::vector, std::allocator >, std::allocator, std::allocator > > >]«
/home/languitar/workspace/iMN/src/algorithms/parallelScan/ParallelScan.cpp:128: instantiated from here
/usr/local/include/boost/mpi/detail/mpi_datatype_cache.hpp:68: Fehler: keine passende Funktion für Aufruf von »assertion_failed(mpl_::failed************ boost::mpi::is_mpi_datatype, std::allocator > >::************)«
/usr/local/include/boost/mpi/detail/mpi_datatype_oarchive.hpp: In constructor »boost::mpi::detail::mpi_datatype_oarchive::mpi_datatype_oarchive(const T&) [with T = std::basic_string, std::allocator >]«:
/usr/local/include/boost/mpi/detail/mpi_datatype_cache.hpp:75: instantiated from »ompi_datatype_t* boost::mpi::detail::mpi_datatype_map::datatype(const T&, typename boost::disable_if, void>::type*) [with T = std::basic_string, std::allocator >]«
/usr/local/include/boost/mpi/datatype.hpp:185: instantiated from »ompi_datatype_t* boost::mpi::get_mpi_datatype(const T&) [with T = std::basic_string, std::allocator >]«
/usr/local/include/boost/mpi/detail/mpi_datatype_primitive.hpp:96: instantiated from »void boost::mpi::detail::mpi_datatype_primitive::save(const T&) [with T = std::basic_string, std::allocator >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:95: instantiated from »static void boost::archive::save_access::save_primitive(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::basic_string, std::allocator >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:212: instantiated from »static void boost::archive::detail::save_non_pointer_type::save_primitive::invoke(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::basic_string, std::allocator >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:294: instantiated from »static void boost::archive::detail::save_non_pointer_type::invoke(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::basic_string, std::allocator >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:506: instantiated from »void boost::archive::save(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::basic_string, std::allocator >]«
/usr/local/include/boost/mpi/detail/ignore_skeleton_oarchive.hpp:46: instantiated from »void boost::mpi::detail::ignore_skeleton_oarchive::save_override(const T&, int) [with T = std::basic_string, std::allocator >, Archive = boost::mpi::detail::mpi_datatype_oarchive]«
/usr/local/include/boost/archive/detail/interface_oarchive.hpp:64: instantiated from »Archive& boost::archive::detail::interface_oarchive::operator<<(T&) [with T = const std::basic_string, std::allocator >, Archive = boost::mpi::detail::mpi_datatype_oarchive]«
/usr/local/include/boost/serialization/nvp.hpp:78: instantiated from »void boost::serialization::nvp::save(Archivex&, unsigned int) const [with Archivex = boost::mpi::detail::mpi_datatype_oarchive, T = const std::basic_string, std::allocator >]«
/usr/local/include/boost/serialization/access.hpp:93: instantiated from »static void boost::serialization::access::member_save(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = const boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/serialization/split_member.hpp:43: instantiated from »static void boost::serialization::detail::member_saver::invoke(Archive&, const T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/serialization/split_member.hpp:69: instantiated from »void boost::serialization::split_member(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/serialization/nvp.hpp:88: instantiated from »void boost::serialization::nvp::serialize(Archive&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = const std::basic_string, std::allocator >]«
/usr/local/include/boost/serialization/access.hpp:109: instantiated from »static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/serialization/serialization.hpp:74: instantiated from »void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/serialization/serialization.hpp:133: instantiated from »void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:220: instantiated from »static void boost::archive::detail::save_non_pointer_type::save_only::invoke(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:294: instantiated from »static void boost::archive::detail::save_non_pointer_type::invoke(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:506: instantiated from »void boost::archive::save(Archive&, const T&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = boost::serialization::nvp, std::allocator > >]«
/usr/local/include/boost/mpi/detail/ignore_skeleton_oarchive.hpp:46: instantiated from »void boost::mpi::detail::ignore_skeleton_oarchive::save_override(const T&, int) [with T = boost::serialization::nvp, std::allocator > >, Archive = boost::mpi::detail::mpi_datatype_oarchive]«
/usr/local/include/boost/archive/detail/interface_oarchive.hpp:64: instantiated from »Archive& boost::archive::detail::interface_oarchive::operator<<(T&) [with T = const boost::serialization::nvp, std::allocator > >, Archive = boost::mpi::detail::mpi_datatype_oarchive]«
/usr/local/include/boost/serialization/collections_save_imp.hpp:60: instantiated from »void boost::serialization::stl::save_collection(Archive&, const Container&) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, Container = std::vector, std::allocator >, std::allocator, std::allocator > > >]«
/usr/local/include/boost/serialization/vector.hpp:53: instantiated from »void boost::serialization::save(Archive&, const std::vector&, unsigned int, mpl_::false_) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, U = std::basic_string, std::allocator >, Allocator = std::allocator, std::allocator > >]«
/usr/local/include/boost/serialization/vector.hpp:123: instantiated from »void boost::serialization::save(Archive&, const std::vector&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, U = std::basic_string, std::allocator >, Allocator = std::allocator, std::allocator > >]«
/usr/local/include/boost/serialization/split_free.hpp:45: instantiated from »static void boost::serialization::free_saver::invoke(Archive&, const T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::vector, std::allocator >, std::allocator, std::allocator > > >]«
/usr/local/include/boost/serialization/split_free.hpp:74: instantiated from »void boost::serialization::split_free(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::vector, std::allocator >, std::allocator, std::allocator > > >]«
/usr/local/include/boost/serialization/vector.hpp:147: instantiated from »void boost::serialization::serialize(Archive&, std::vector&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, U = std::basic_string, std::allocator >, Allocator = std::allocator, std::allocator > >]«
/usr/local/include/boost/serialization/serialization.hpp:133: instantiated from »void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::vector, std::allocator >, std::allocator, std::allocator > > >]«
/usr/local/include/boost/archive/detail/oserializer.hpp:144: instantiated from »void boost::archive::detail::oserializer::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::mpi::detail::mpi_datatype_oarchive, T = std::vector, std::allocator >, std::allocator, std::allocator > > >]«
/home/languitar/workspace/iMN/src/algorithms/parallelScan/ParallelScan.cpp:128: instantiated from here
/usr/local/include/boost/mpi/detail/mpi_datatype_oarchive.hpp:36: Fehler: keine passende Funktion für Aufruf von »assertion_failed(mpl_::failed************ boost::mpi::is_mpi_datatype, std::allocator > >::************)«
make[2]: *** [src/CMakeFiles/imnbase.dir/algorithms/parallelScan/ParallelScan.cpp.o] Fehler 1
make[1]: *** [src/CMakeFiles/imnbase.dir/all] Fehler 2
make: *** [all] Fehler 2

Übersichtlich…

11.07.2009

Highlights aus Graz

Doppelhaltestelle

Doppelhaltestelle

Buchstabenschwund

Buchstabenschwund

Zeitloch

Zeitloch?

Enigmail hat auf meinem neuen Laptop mit dem kopierten Home-Directory den Dienst verweigert. Bevor ich überhaupt eine Passphrase eingeben konnte erschien bereits die Meldung, dass ich eine falsche eingegeben hätte. Das Problem war auf der Konsole dann noch etwas konkreter sichtbar:

gpg: Schwierigkeiten mit dem Agenten - Agent-Ansteuerung wird abgeschaltet

Lange Rede, kurzer Sinn: der gpg-agent lief, aber ihm fehlte das entsprechende Programm um den Eingabedialog für das Passwort anzuzeigen. Da der gpg-agent von meiner KDE-Sitzung gestartet wurde, hat pinentry-qt gefehlt. Seltsamerweise wird in Jaunty unter KDE4 nicht pinentry-qt4 benutzt, was bereits installiert war.

In der Java-Welt gibt es schon lange die sinnvolle Konvention kompilierte class-Dateien in einer anderen Verzeichnisstruktur abzulegen als den Quellcode. So eine eine Konvention hat viele Vorteile:

  • Falls der Quellcode in ein Versionskontrollsystem eingecheckt wird (und das sollte er auf jeden Fall), müssen nicht umständliche Regeln zum Excluden der kompilierten Dateien geschrieben werden.
  • Dateioperationen im Source-Tree (z. B. ein Aufruf von find oder grep) müssen nicht aufwendig um die kompilierten Dateien herumgelenkt werden

Leider ist dies in der C++-Welt teilweise noch nicht ganz angekommen, deshalb hier ein kurzer Reminder, wie solche “Out-of-Source Builds” mit CMake gemacht werden können.

Das schöne an CMake ist, dass man eigentlich gar nichts tun muss, um ein Out-of-Source Build zu erstellen. Angenommen die Projektstruktur sie so aus:
languitar@bird /tmp/cmakeexample $ find
.
./bin
./src
./src/yourCodeHere.cpp
./CMakeLists.txt

Um jetzt ein Out-of-Source Build zu erstellen, bei dem alle kompilierten Dateien in bin abgelegt werden, reicht es in das bin-Verzeichnis zu navigieren und dort cmake .. aufzurufen. Alle Dateien, die CMake intern benötigt, inklusive des generierten Makefiles,  und alle Ergebnisse des Compilers / Linkers werden so in bin angelegt und sowohl src als auch der Projektordner bleiben unangetastet. Diese Vorgehen hat bei CMake auch noch einen besonderen Vorteil: Eigentlich sollte CMake Änderungen an der CMakeLists.txt eigenständig feststellen und das Makefile neu generieren beim Bauen. Das klappt des Öfteren jedoch nicht richtig. Hätte man CMake im Projektverzeichnis aufgerufen müsste man dort jetzt mühselig alle von ihm generierten Dateien wie den CMakeCache.txt löschen um von vorne anzufangen. Im Falle eines Out-of-Source Builds kann man hingegen bedenkenlos und einfach den Build-Ordner leeren.

Ein paar Kleinigkeiten muss man für saubere Out-of-Source Builds mit CMake allerdings doch noch beachten. Auch wenn CMake das eigentliche Bauen und das Verwalten der internen Dateien sauber im Build-Ordner durchführt, verhindert es keine Fehler durch den Anwender. Falls man CMake z. B. noch selbst benutzt um Dateien zu generieren (z. B. pkg-config Files) sollten diese auch im Build-Ordner erstellt werden. Dieses Verzeichnis kann man in CMake mit den Variablen CMAKE_BINARY_DIR bzw. CMAKE_CURRENT_BINARY_DIR abfragen. Dateien sollten also immer über diese Variablen gespeichert werden und nicht über CMAKE_SOURCE_DIR bzw. CMAKE_CURRENT_SOURCE_DIR. Im Falle eines “In-Source” Builds (also der Aufruf cmake . im Projektordner) zeigen CMAKE_BINARY_DIR und CMAKE_SOURCE_DIR etc. übrigens auf dieselben Verzeichnisse.

Alle paar Monate stolper ich in irgendwelchem Code über das gleiche Problem bei der Implementierung des Observer-Patterns in  Java. Deshalb hier noch mal ein kurzer Reminder, was man beachten sollte.

Häufig sieht man Implementierungen wie diese:

  1.  
  2. public class ObserverTest {
  3.  
  4.     private static interface Observer {
  5.         void process();
  6.     }
  7.  
  8.     private static Set<Observer> observers = new HashSet<Observer>();
  9.  
  10.     public static void addObserver(Observer observer) {
  11.         observers.add(observer);
  12.     }
  13.  
  14.     public static void removeObserver(Observer observer) {
  15.         observers.remove(observer);
  16.     }
  17.  
  18.     private static void notifyObservers() {
  19.         for (Observer o : observers) {
  20.             o.process();
  21.         }
  22.     }
  23.  
  24.     // es fehlt noch eine main-Methode
  25.  
  26. }
  27.  

Das funktioniert so auch in vielen Fällen problemlos, in folgendem Fall aber nicht:

  1.  
  2. public static void main(String[] args) {
  3.  
  4.     addObserver(new Observer() {
  5.  
  6.         @Override
  7.         public void process() {
  8.             removeObserver(this);
  9.         }
  10.  
  11.     });
  12.  
  13.     notifyObservers();
  14.  
  15. }
  16.  

Führt man das Programm so aus, wirft Java eine ConcurrentModificationException:

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:761)
at java.util.LinkedList$ListItr.next(LinkedList.java:696)
at ObserverTest.notifyObservers(ObserverTest.java:21)
at ObserverTest.main(ObserverTest.java:37)

Das Problem hier ist, dass eigentlich alle Standardimplementationen von Collection keine Änderung beim iterieren zulassen. Diese Beschränkung sollte man normalerweise aber nicht an die Observer weiterreichen, da sie deren Handlungsfähigkeit stark einschränkt (ein üblicher Anwendungsfall ist, dass sich ein Observer abmeldet, wenn er die gewünschte Information erhalten hat). Zum Glück gibt es eine sehr einfache Lösung für dieses Problem: vor dem Iterieren holt man sich eine Kopie der Collection und iteriert über diese (hierbei muss beachtet werden, dass es eine “shallow copy” ist, also die Elemente selbst nicht Kopiert werden, nur der Container).

Mit folgender Modifikation läuft der Code also problemlos durch:

  1.  
  2. private static void notifyObservers() {
  3.     Set<Observer> observersCopy = new HashSet<Observer>(observers);
  4.     for (Observer o : observersCopy) {
  5.         o.process();
  6.     }
  7. }
  8.  

Google meint es wohl gerade etwas zu gut damit arme Internetnutzer vor den Gefahren  des WWW zu warnen und stuft das komplette Internet als Malware-gefährdet ein – inklusive sich selbst.

Google - Diese Website kann Ihren Computer beschädigen.

Google - Diese Website kann Ihren Computer beschädigen.

Vielleicht wird es doch Zeit, sich nach einer Alternative umzuschauen…

Kategorien