I've been working on various projects. The interesting ones are listed over here, with the top of the list containing the most active ones.
It's time for another programming contest this weekend: the ACM 2007 Northwest European Programming Contest, or NWERC 2007 for short. The R in NWERC is for Regional instead of Programming; I didn't make that up ;)
I'll be competing with the same team as the BAPC where we reached the fifth spot. I'm counting on a place in the upper half at least, hopefully somewhere in the upper regions of the entire competition. The problem set will be available afterwards, probabaly from the NWERC site.
For the BAPC, the problems sets can be found on the BAPC site at http://www.bapc.nl/?p=problems.
I've spent quite some time on this problem, and it keeps popping up every time I'm coding with dynamically loadable modules in C++. The POSIX-interface to use dynamically loadable modules (libdl) defines a number of C functions to work with these modules: dlopen() and friends.
These functions are all nice in that they work nicely when used in C++ with one major exception: dlsym(). This function is used to find a symbol inside a dynamically loaded module. The symbol which is looked up can be any symbol: a pointer, a variable, a function, etc. The way to return a pointer to some unknown type is by using a void pointer.
Returning a void pointer might seem logical for this, but there is one big problem: it can return either a variable or a function. There is no issue when type-casting a void pointer to a pointer to some other type. Type-casting a void pointer (which is in essence a variable) to a function pointer is not that straightforward: function pointers can be fundamentally different.
Imagine a system where there are separate memories for code and for data. Because the system works with loads of code but small amounts of data, the code memory will need 32 bits pointers while the data memory only needs 16 bits pointers. The void pointer returned by dlsym() will be a pointer to data: it will be 16 bits. When this is actually a function, it has to be type-casted to a function pointer, but that requires a 32 bits pointer. There is no way that all 32 bits can be retrieved from the 16 bits of information we got from dlsym().
It is because of the above example that the behavior of type-casting between data-pointers and function-pointers is undefined in C. Most compilers nevertheless provide working behavior for this though, and it is exactly this behavior that the dlsym() function requires. In the revised C99 standard, it is mentioned as a common extension to the language.
When it comes to C++, the C++ Standard Core Language Defect #195 is exactly about this issue: converting between function and object (data, variable) pointers. They've worked out a (not yet officially accepted) proposal to fix this issue: on implementations which can provide this sort of casts it works and on implementations which cannot provide a cast between function and object pointers the cast would either be undefined or throw an error or warning during compile time.
With the default warning levels, most compilers do not complain about casting an object pointer to a function pointer. I, however, tend to code with certain strict checking flags on to catch some small mistakes or ambiguities that might get in my code. When compiling the module code of IRC Cantus , about which i will blog soon, this means that I will get a warning every time i use dlsym():
g++ -W -Wall -g -pedantic -g -O2 -export-dynamic -I../include -c cantus.cpp g++ -W -Wall -g -pedantic -g -O2 -export-dynamic -I../include -c argument.cpp g++ -W -Wall -g -pedantic -g -O2 -export-dynamic -I../include -c config.cpp g++ -W -Wall -g -pedantic -g -O2 -export-dynamic -I../include -c log.cpp g++ -W -Wall -g -pedantic -g -O2 -export-dynamic -I../include -c log_facilities.cpp g++ -W -Wall -g -pedantic -g -O2 -export-dynamic -I../include -c main.cpp g++ -W -Wall -g -pedantic -g -O2 -export-dynamic -I../include -c module.cpp g++ -W -Wall -g -pedantic -g -O2 -export-dynamic -I../include -c modulesupport.cpp modulesupport.cpp: In member function ‘void module::Instance::open()’: modulesupport.cpp:85: warning: dereferencing type-punned pointer will break strict-aliasing rules modulesupport.cpp: In member function ‘void module::Instance::close()’: modulesupport.cpp:109: warning: dereferencing type-punned pointer will break strict-aliasing rules g++ -W -Wall -g -pedantic -g -O2 -export-dynamic -I../include cantus.o argument.o config.o log.o log_facilities.o main.o module.o modulesupport.o -o cantus -ldl
This warnings obviously ruin the clean, warning-less output I would get without these issues ;) For now there is no way to get this to compile without warnings without dropping some of the warning reporting flags, which is obviously not what I want. There seems to be no solution to this problem at all; people I ask about it do not come any further than joking about the choice of wording for type-punned...
Today the first test competition of the CodeCup 2008 will be held. The CodeCup is a yearly programming competition where you have to write a program which plays a multiplayer (usually 2 players) game. The games are usually variations on board games.
This year's game is Alquerque, a variation on checkers. You start with a board filled with white and black squares and have to take turns in capturing each other's pieces. The first to catch all of the opponents pieces or trap the opponent wins.
I recently had a chat with DrStein, project leader of the Denora IRC Statistics project, about the future of both Anope and Denora. We both want to move to C++ with the next generation core and since we both basically are U:lined servers with slightly different clients, we thought we could work together on a brand new C++ core for both of our projects.
Details are still sparse since we still need to work out the details, but I am pretty sure this will lead to a decent, project-independent core. Having two projects using the core from start will allow us to fine-tune the core to include everything both of us need, but exclude everything that would make the core only really usable for a single project (like with the current Anope core).
I will post more news on this when there are plans on how things will take shape :)
The people over at IBM have created a nice overview of the various components of the Linux kernel. The article gives a quick history of Linux and then moves on to explain the various parts existing in the Linux kernel. The article has been written to give a better understanding of the structure of the over five million lines of source code the kernel consists of. There are a also number of very useful links at the end of the article to more in-depth resources about various parts of the kernel.
The Linux® kernel is the core of a large and complex operating system, and while it's huge, it is well organized in terms of subsystems and layers. In this article, you explore the general structure of the Linux kernel and get to know its major subsystems and core interfaces. Where possible, you get links to other IBM articles to help you dig deeper.