Older blog entries for redi (starting at number 229)

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.

chalst, don't the ratings only get recalculated periodically? Your report shows 6 now, with a confidence of 1 (i.e. you set it explicitly)
13 Aug 2010 (updated 13 Aug 2010 at 17:15 UTC) »

Rogerio Rilhas, long-winded idiot or successful troll?

12 Aug 2010 (updated 13 Aug 2010 at 08:12 UTC) »

argh! advogato's diary entry form is ****

... too narrow. And very annoyingly splits lines up.

12 Aug 2010 (updated 12 Aug 2010 at 23:46 UTC) »

apenwarr writes:

Well, it means we're headed for trouble. Intel and other chip manufacturers are insistent that we need to update our programs - and thus our programming languages - to do more stuff with threads. Watch out, they say, because soon, there'll be no way to make your program fast unless you use multiple cores simultaneously. And that means threads, which means garbage collection instead of refcounting, which means non-deterministic destructors.

Or you stick with refcounting and deterministic destructors, and minimise data sharing between threads.

One option is to have different refcounting policies, so that some counts are not threadsafe and use simple integer increments/decrements without memory synchronisation, while counts for objects which are shared between threads use slightly slower, synchronised operations.

That can work well, although it isn't foolproof. You need to be strict about never sharing objects with unsync'd refcounts and need to know in advance whether you'll want to share an object because you can't easily convert between sync'd and unsync'd refcounts.

22 Jul 2010 (updated 22 Jul 2010 at 10:53 UTC) »
apenwarr's repeated suggestion for operator[]= is silly, that only helps types which have an operator[].

A better, more general solution is already in C++0x: Move Semantics. That removes performance overheads that copy elision (e.g. RVO) can't help with, in all sorts of situations, not just Avery's specific one for std::map.

And if you want the behaviour of python dictionaries, that's trivial:


template<typename Map, typename K>
typename Map::mapped_type&
get(Map& map, K&& key)
{
    auto pos = map.find(key);
    if (pos == map.end())
        throw std::runtime_error("Not found");
    return pos->second;
}

That works for anything with the same interface as std::map and allows get(m, 5) = "chicken" to work as you want, with no loss of efficiency*

The constructive criticism is valid, but years too late. C++0x has closures (which have zero overhead compared to a C function unless you need it, and can even be converted to C function pointers and passed to existing APIs,) it has typesafe varargs, and thanks to move semantics it can be significantly faster than C at copying data structures around, so there's no reason for functions to take out parameters by pointer/reference, just return them and watch the copies not happen. It also has type inference, and explicit conversion operators, which only convert when you want them to e.g. a smart pointer's conversion to bool happens if used in an if but not if you try to assign it to an int.

The bad parts of C++ may not have been removed, but some seriously good stuff has been added. (Edit: all of the above is available today in GCC.)

Oh, and exception handling is not too complicated. You must be doing it wrong.

* Actually a better version would use


typename Map::key_type key2(std::forward<K>(key));
map.find(key2);
for maximum efficiency in the case where K is not the same type as key_type and requires a conversion.
johnw writes But where Haskell needs Monads to make this type of thing reasonable and concise, C++ doesn’t. We get passing around of object state between function calls as part of the core language, and there are many different ways to express it.

I'm not sure that's necessarily a good thing. The hoops you have to jump through in Haskell to get stateful, sequential behaviour mean that it's a clear and conscious decision to do so, and you have a well-defined tool with which to reason about your program. In C++ that behaviour is hard to avoid, and might be incidental or even accidental, rather than explicit and desirable.

If you did have monads in your C++ program, they'd probably be leaky abstractions and it would be too easy to misuse them by combining them with "normal" code, so that you lose the benefit. In Haskell they are fenced off and harder to mis-apply (as I understand it, anyway.)

220 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!