LIBPF builds with clang++

Clang++ is a new generation C++ compiler, based on a complete redesign. According to the reports it can not yet match compilation and execution time of the more mature competitors (g++, msvc, intel…), but it is growing up really quickly: the successful compilation of the boost libraries has been announced about one year ago. It was definitely time to give it a try with the LIBPF library, which we did on Debian testing (sid).

Compiling LIBPF on Debian sid, by the way, is much easier than what it used to be because over the years all the dependencies have been packaged (previously there was no libloki-dev and libsilo-dev package available). What is required nowadays to compile the LIBPF library with the default compiler on Linux (g++) is just:

apt-get install git g++ libboost1.46-dev xsltproc libloki-dev libpq-dev libsqlite3-dev libgmm++-dev libiodbc2-dev libsundials-serial-dev libmxml-dev libsilo-dev libsuitesparse-dev
git clone ...
cd LIBPF/src
bjam

To compile with clang version 2.9-7 you need to issue the following two commands:

apt-get install clang
bjam toolset=clang

Treating your (supposedly) standard-complying C++ code with a new compiler always brings in some new insight. Clang++ benefits here are the precise error / warning messages and the stricter syntax parser. The main lesson learned thanks to clang was that the right way to define a static member and instantiate a template class is:

template<> std::string PhaseIdeal<PhaseType::vapor>::type_("PhaseIdeal<vapor>");
template<> std::string PhaseIdeal<PhaseType::liquid>::type_("PhaseIdeal<liquid>");
template<> std::string PhaseIdeal<PhaseType::solid>::type_("PhaseIdeal<solid>");
template class PhaseIdeal<PhaseType::vapor>;
template class PhaseIdeal<PhaseType::liquid>;
template class PhaseIdeal<PhaseType::solid>;

and not the other way around (which is tolerated by all other compilers):

template class PhaseIdeal<PhaseType::vapor>;
template class PhaseIdeal<PhaseType::liquid>;
template class PhaseIdeal<PhaseType::solid>;
template<> std::string PhaseIdeal<PhaseType::vapor>::type_("PhaseIdeal<vapor>");
template<> std::string PhaseIdeal<PhaseType::liquid>::type_("PhaseIdeal<liquid>");
template<> std::string PhaseIdeal<PhaseType::solid>::type_("PhaseIdeal<solid>");

And now some performance data, obtained on a somewhat outdated, single-core workstation:

Performance criterion g++ 4.6.1 clang++ 2.9-7
debug release debug release
Compilation time 6m27.550s 10m26.199s 7m26.881s 10m56.789s
Executable size (Mbytes) 24.1 7.6 42.1 10.1
Execution time 10m10.655s 11m30.840s

Clang++ has still some way to go before entering the A league, but it is already today a valuable code compliance tool.