Older blog entries for redi (starting at number 226)

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));
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.)

Also, the RVO doesn't rely on inlining, and there's no default construction or assignment operator in that example, MyObj x = ... is a constructor call not an assignment.

Sure RVO is a hack, but it's a safe and useful one (in many more situations than apenwarr's map case) so why do you care? Any why would anyone ever ever use C++ without an optimising compiler?! If you don't care enough about performance to use a decent compiler then why are you using C++ in the first place?

The only downside to the RVO (apart from the fact that the wikipedia article is incomplete and doesn't distinguish RVO and NRVO) is if you're relying on side effects of copy constructors, but that usually only happens in toy code people write to try and understand C++ rules.

My only other quibble is with the statement that you always know 'this' when you create a pointer-to-member-function. If that's how you use PMFs no wonder you don't find them useful ;)

8 Jul 2010 (updated 8 Jul 2010 at 00:42 UTC) »
If you love LLVM so much why don't you go live there?

I think it's healthy and important for a best-in-class software product to have serious competition from at least one other project (look what a stinking pile of slow Firefox has become - go Chrome!) and I can't begin to explain how highly I respect some of the developers working on clang++ and libc++.

But I get a teeny bit wound up by users who say "I haven't used Project X, but I hear it does Y and Z, and your project sucks because it doesn't do that!"


If it's so important to you, at least try it out, and if it actually does something differently, please let us know how we can improve.

But if you can't even be bothered to try it out, don't expect to be taken seriously.

8 Jun 2010 (updated 8 Jun 2010 at 10:30 UTC) »

Hey, Observers. If any of you are really interested in open source and are interested in this site for anything other than SEO opportunities, here are some ideas for mini-projects to improve Advogato:

  • Convert <h1>, <h2> etc. tags in syndicated diary entries to something sensible. I suggest simply <p>. Advogato diary entries are not allowed heading elements, so they get converted to &lt;h1&gt; and come out verbatim, not even on a new line (example)

  • Change the new account page where it says Attention spammers. I suspect SEO-scum do not consider themselves spammers and that they think their SEO-scum activities are acceptable behaviour. If the notice said Attention SEO workers it might get their attention. Now if only there was some way to find out where they live and send them a turd in a box ...

These should both be pretty easy and might earn you kudos from the users of this site. Even trying to do it would get you a certification from me. Get the code for mod_virgule (make sure you get StevenRainwater's new fork) and start hacking. I'd be happy to review patches or help you with any problems using subversion or building the code. Post (links to) patches in your diary or send them to robogato.

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