Older blog entries for redi (starting at number 235)

2 Mar 2011 (updated 2 Mar 2011 at 15:24 UTC) »

In C++ foldr is pronounced std::accumulate and map is pronounced std::transform.

I don't think we have a word for unfold, but I guess I'd say it like this:


template<class OutIt, class P, class F, class G, class T>
size_t
unfold(OutIt result, P stop, F f, G g, T x)
{
    if (stop(x))
        return 0;
    *result = f(x);
    return 1 + unfold(++result, stop, f, g, g(x));
}

Edit: hmm, no I wouldn't, it's unspecified whether g or g(x) gets evaluated first, which matters if G is stateful (which it shouldn't be, but have ever tried telling a C++ programmer they shouldn't use a sharp object?) A workaround would be to pass stateful functors in by reference, e.g. using a reference wrapper such as boost::ref or std::ref but it'd be nice if that wasn't needed. I'll have to think about that further ...

audriusa please fix your diary entry, it's fscking up the following entry on recentlog
20 Jan 2011 (updated 20 Jan 2011 at 10:52 UTC) »
The Empire Strikes Back

Like chalst, I'm pleased there are still some interesting unsyndicated diaries in recentlog. If only they weren't massively outnumbered by the new spam accounts created every day.

17 Jan 2011 (updated 19 Jan 2011 at 09:40 UTC) »

kill the spammer below this post [he got killed, but despite blocking his IP range he's back again]

someone patch mod_virgule to reject all accounts from repeat spammer "tarunyadavseo" - please click on his name in "New advogato members" and mark his account as spam. Then find him and set fire to him.

6 Jan 2011 (updated 6 Jan 2011 at 20:08 UTC) »
Adventures in C++ compiler land

I've ventured into the g++ front end a couple of times recently (I usually only touch libstdc++ code) trying to fix some bugs. I haven't managed to get my patches reviewed, but as stage 3 has ended I'll have to wait until 4.6 is branched and then try to get them into 4.7

More clang bangin'

One of the goals/features of Clang/LLVM is faster compile times than GCC, so I think something's very wrong with my build (which I configured as a "Release+Asserts build"):


$ wc -l src/Order.cc
4107 src/Order.cc
$ time make CXX=g++ objs/Order.o
...
real    0m8.993s
user    0m8.483s
sys     0m0.339s
$ time make CXX=g++ CXXFLAGS="-O2 -DNDEBUG" objs/Order.o
...
real    0m12.111s
user    0m11.999s
sys     0m0.309s
$ time make CXX=clang++ objs/Order.o
...
real    2m11.608s
user    2m7.475s
sys     0m0.260s
$ time make CXX=clang++ CXXFLAGS="-O2 -DNDEBUG" objs/Order.o
...
real    17m22.577s
user    17m21.589s
sys     0m0.377s

Yes, that really did take 17 minutes at 100% CPU (on a 2.93GHz Xeon X5570) compared to 12 seconds for GCC.

One of the things I really like is that most of GCC's command-line options are supported. so I used -ftime-report to see where all that time is spent, but all the detailed stats are for the code generation stages, which is the only bit that isn't slow!

---User Time--- --System Time-- --User+System-- ---Wall Time--- --- Name ---
137.5871 ( 50.6%) 0.2380 ( 67.8%) 137.8250 ( 50.6%) 138.0570 ( 50.6%) Clang front-end timer
131.2420 ( 48.2%) 0.0610 ( 17.4%) 131.3030 ( 48.2%) 131.3707 ( 48.2%) LLVM IR Generation Time
3.1755 ( 1.2%) 0.0520 ( 14.8%) 3.2275 ( 1.2%) 3.2308 ( 1.2%) Code Generation Time
272.0046 (100.0%) 0.3509 (100.0%) 272.3556 (100.0%) 272.6585 (100.0%) Total

That was with a build from subversion a few weeks ago (trunk 121966) so I updated and got sensible times, although the optimised build is still slower than I expected:


$ time make CXX=clang++ objs/Order.o
...
real    0m7.380s
user    0m6.674s
sys     0m0.471s
$ time make CXX=clang++ CXXFLAGS="-O2 -DNDEBUG" objs/Order.o
...
real    0m17.667s
user    0m17.131s
sys     0m0.309s

I don't remember the earlier build being so slow a few weeks ago, so maybe some gremlins came and moved the files to a really slow bit of the filesystem over Christmas.

Using Clang on a large codebase did find a few bugs which GCC and Sun CC didn't object to (one notable feature is that clang++ found errors in templates which were never instantiated, which even EDG didn't find) and I also found a bug in clang, but one of the main reasons I wanted to try it was the static analyzer. Unfortunately it only works for C and Obj-C and trying to analyze C++ fails miserably. I guess I'll wait and try it again at a later date.

24 Dec 2010 (updated 3 May 2011 at 20:30 UTC) »

If you want to build gcc from source, for any released version since 3.0 (or something equally ancient,) or a recent snapshot, use this makefile

config-gcc.mk

download it, put it in a new dir, and run gmake -f config-gcc.mk, then do what it tells you to do

You can do exciting things such as

gmake -f config-gcc.mk GCC_VERSION=4.6-20101218 MPFR_VERSION=3.0.1 LOCAL_SRC=$HOME/Downloads

to build a specific version (including snapshots) with specific versions of the GMP, MPFR and MPC prerequisites, and to use tarballs from a local directory if you've already downloaded them.

Clang is nice for a holiday but I wouldn't want to live there

If you have GCC installed in a non-standard location or are using a Linux distro Clang doesn't know about then the following patch is needed to get a working compiler, where /your/gcc/prefix is the location of your gcc installation, and X.Y.Z is the output of '/your/gcc/prefix/bin/gcc -dumpversion'

(This should all possible for configure to detect from the output of 'gcc -print-libgcc-file-name' so you don't need to hack the code, but Clang prefers to hardcode the paths for various known distros ... I expect better from the core clang devs, so I assume they only care about supporting apple and the linux hacks have been added by distro packagers, who only care about making their specific packages work.)

Without this hack, clang can't figure out where to find crtbegin.o and crtend.o and so it invokes ld incorrectly, in the worst case this results in


/usr/bin/ld: crtbegin.o: No such file: No such file or directory
clang: error: linker command failed with exit code 1 (use -v
to see invocation)

I don't plan to improve on my hack, because it's difficult to test the results on my Fedora box, where the existing hardcoded hacks make clang appear to work correctly (but actually it's finding the system compiler not the one I want it to use.) As a GCC maintainer I'm not going to uninstall my system gcc just to help fix a competitor's hack ;-)

Determining header and library search paths properly would probably speed up clang a little, as it wouldn't need to check for dozens of nonexistent directories that might exist if you were using a different distro and/or gcc release. Not that clang needs any help running faster than gcc.

(mod_virgule will mangle this patch but maybe it'll still be useful to someone)


Index: lib/Frontend/InitHeaderSearch.cpp
===================================================================
--- lib/Frontend/InitHeaderSearch.cpp   (revision 121966)
+++ lib/Frontend/InitHeaderSearch.cpp   (working copy)
@@ -612,6 +612,10 @@
     AddPath("/usr/include/c++/4.1", System, true, false,
false);
     break;
   case llvm::Triple::Linux:
+
AddGnuCPlusPlusIncludePaths("/your/gcc/prefix/include/c++/X.Y.Z",
+   "x86_64-unknown-linux-gnu", "32", "", triple);
+
AddGnuCPlusPlusIncludePaths("/your/gcc/prefix/include/c++/X.Y.Z",
+   "x86_64-unknown-linux-gnu", "", "", triple);
    
//===------------------------------------------------------------------===//
     // Debian based distros.
     // Note: these distros symlink /usr/include/c++/X.Y.Z
-> X.Y
Index: lib/Driver/ToolChains.cpp
===================================================================
--- lib/Driver/ToolChains.cpp   (revision 121966)
+++ lib/Driver/ToolChains.cpp   (working copy)
@@ -1321,6 +1321,11 @@
     if
(llvm::sys::Path("/usr/lib/gcc/arm-linux-gnueabi").exists())
       GccTriple = "arm-linux-gnueabi";
   } else if (Arch == llvm::Triple::x86_64) {
+
+    if
(llvm::sys::Path("/your/gcc/prefix/lib/gcc/x86_64-unknown-linux-gnu").exists())
+      GccTriple = "x86_64-unknown-linux-gnu";
+    else
+
     if
(llvm::sys::Path("/usr/lib/gcc/x86_64-linux-gnu").exists())
       GccTriple = "x86_64-linux-gnu";
     else if
(llvm::sys::Path("/usr/lib/gcc/x86_64-unknown-linux-gnu").exists())
@@ -1349,7 +1354,7 @@
   std::string Base = "";
   for (unsigned i = 0; i <
sizeof(GccVersions)/sizeof(char*); ++i) {
     std::string Suffix = GccTriple + "/" + GccVersions[i];
-    std::string t1 = "/usr/lib/gcc/" + Suffix;
+    std::string t1 = "/your/gcc/prefix/lib/gcc/" + Suffix;
     if (llvm::sys::Path(t1 + "/crtbegin.o").exists()) {
       Base = t1;
       break;

Comedy spam account of the day:

Notes: I'm a dental hygienist looking for a new place to work

Free software or GTFO!

3 Dec 2010 (updated 3 Dec 2010 at 22:19 UTC) »

I found these nice C++0x additions for vim: Add support of C++0x in cpp.vim. Now I have suitable syntax highlighting for constexpr and other new keywords. C++0x lambda functions still confuse syntax highlighting though, I suspect that'll take a bit more effort to fix. Or maybe it's OK to have lambdas highlighted in bright red, I guess that could be considered a feature!

I'm working on new pieces of the C++0x standard library for libstdc++ and the more I use it, the more I find that C++0x is a joy to program in. Yes, that's right, C++. Not a pain in the butt. A joy. Personally I've always liked using C++, but in what some might consider a perverse way - with C++0x I think there's a dash of elegance to go with the power that C++ has always had. (But maybe I'm just braindamaged by too many years of using templates.)

RAII combines very nicely with move semantics, so not only can you manage resources 100% safely and simply, you can now transfer ownership of those resources efficiently and 100% safely. Resource Transfer Is Initialization too, thanks to move constructors.

Tuples are like std::pair on steroids, but whereas the only helper for pairs was std::make_pair, C++0x gives you a handful of tuple helpers: make_tuple, tie, forward_as_tuple, tuple_cat. These make it very convenient to pass ad-hoc data structures in and out of functions. Especially when you combine them with type inference, done with the re-purposed auto keyword and template argument deduction - which itself is made more powerful and at the same time simpler, thanks to variadic templates.

Using these new features I've just implemented std::try_lock() and std::lock(), the generic locking algorithms that lock an arbitrary number of Lockable arguments (typically two or more std::mutex objects) and it took me roughly the same number of lines of code as a similar try-and-backoff algorithm in Butenhof's book, which only handles a fixed number of mutexes (three) and doesn't have robust error-handling (abort), and of course only works with one type of lock (pthread_mutex_t).

I've seen the future and it tastes like awesome.

226 older entries...

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!