Older blog entries for redi (starting at number 122)

oshani is certified now, thanks to ncm's trust-juice. I'm obviously not close enough to the seeds of the graph for my journeyer status to do any good, as oshani was still an observer after my cert.

robogato, o benevolent robot cat overlord, there's a broken link on the Trust Metric page, for the tmetric.c file in the GNOME CVS repository.

Three cheers for writing documentation

Last week I thought I'd finished implementing Improving shared_ptr for C++0x for GCC: GNU Compiler Collection but have spent the last few days writing more tests and docs on the implementation.

Writing the docs resulted in far larger code changes than the additional testing with funky types and debug allocators. Testing found that I was using the wrong allocator type in one place (so potentially leaking memory, not good for a shared_ptr!) and that I needed to remove a const-qualifier somewhere else, easy with this shiny new std::remove_const meta-function. Only about 5 lines to change. Documenting the "finished" design resulted in several simplifications, a better interface, and the complete removal of some unnecessary code. The difference is partly because my original tests covered most cases, but it still makes me think of Richard Feynman's point that if you can't explain something in simple terms, you don't really understand it. (The much paraphrased original seems to be "I couldn't reduce it to the freshman level. That means we really don't understand it.") Explaining why I'd made certain compromises in the design embarassed me into fixing them, and documenting the unresolved issues made me decide to resolve some of them and give a decent rationale for leaving the others.

I wish I could give the same amount of time to designing, documenting and refactoring some of the code I'm paid to write, but my open-source dabbling benefits from having no deadlines. The shared_ptr changes have been brewing for months. The downside is that some of my PStreams ideas have been idling on a hard disk for years. I really must fix showmanyc.

Cool new C++ feature

C++0x introduces the following function:


template<class T, class... Args>
  shared_ptr<T> make_shared(Args&&... args);

Which is used like so:


class A {
  A(int);
  // ...
};
shared_ptr<A> p = make_shared<A>(99);
// better than: shared_ptr<A> p(new A(99));

This function is cool for two reasons.

First, it only needs a single allocation for the A and the shared_ptr's internal bookkeeping.

Secondly, it gives the strong exception-safety guarantee. Consider:


void f(shared_ptr<A>, shared_ptr<A>);


f(shared_ptr<A>(new A(1)), shared_ptr<A>(new A(2)));

Because C++ doesn't define the order of evaluation here, the compiler is allowed to perform both new operations before calling either shared_ptr constructor. If the second allocation or construction throws an exception, the first object will be leaked.

Today, the usual way to avoid the leak is to avoid calling new twice in that one statement (using a local variable instead of one of the temporaries,) but in The Future we will be able to say:


f(make_shared<A>(1), make_shared<A>(2));
This cannot leak, because both A objects are safely managed by a shared_ptr as soon as they're constructed. RAII to the maaaaaaaax.

So it's cool because it's safer and more efficient. It's one less reason to see naked new delete operators in C++ code.

make_shared() is possible as a library in C++03, but with variadic templates and rvalue-references in C++0x it's really cool. Try it out in GCC 4.3 soon (I hope.)

A few weeks ago I wished that searching for gcc filebuf fd would return the relevant documentation from libstdc++. Well now it does. Thank you, fairy godmother.

Re State of the Gato Address for 2007

ncm points out spammers are still getting through.

Lowering the deletion threshold to 10 would have deleted oshani who appears to be genuine, unless presbrey, and by implication timbl, is attacking the trust metric ;)

I'm one of the frequent users of the spam rating system, but I've been guilty of reporting some users as spam simply because they haven't listed any personal information, only to find that a few days later the profile has been updated and the account looks genuine. A way to undo the spam rating would help here.

As I've mentioned before, the only thing I don't like about the new advogato is the change from "diary" to "blug" (or whatever that word is.) Although overall I'm very happy with Steven's work, I'd still like to see that changed back. And a pony, for ncm.

After a few days offline for my 30th birthday celebrations and a crappy cold, today I made a small commit to libstdc++, so that GCC 4.3 will have a slightly faster shared_ptr in MT apps. Yay. Bigger shared_ptr improvements to follow now that's out of the way.

I'm also familiarising myself with the forthcoming std::unique_ptr, which is not available in GCC yet (there's an implementation but I think it's waiting on copyright assignment paperwork.) I've now put my foot in my mouth on two mailing lists in threads about deprecating auto_ptr, by moaning about non-issues; I'll try not to do it a third time.

Another apparently little-known GCC fact

GCC supports a -pthread option on several platforms, which causes the necessary options for using POSIX threads to be passed to the preprocessor, compiler and linker.

In particular, for GNU/Linux on x86 -pthread passes -D_REENTRANT to the preprocessor and -lpthread to the linker.

The documentation for GCC options doesn't currently mention -pthread except for a few specific architectures. The reasons for this are lengthy, but not very good.

On Solaris, GCC used to only support the -pthreads option, which is how Sun's compiler spells it, but in recent versions of GCC -pthread has the same effect.

(I might post other little-known GCC facts here, in the vain hope it will disseminate the information more widely.)

Bicycle sheds

There is a noisy thread currently taking place on the GCC mailing list arguing over whether compiler optimisations that result in speculative loads are valid in multithreaded programs. Several people have made mistaken claims about guarantees made by POSIX (there are almost none) and others have argued from personal opinion. A few have argued from positions which are technically correct, but incompatible with the proposed C++ memory model. Very few of the participants seem to have bothered to read the link I first posted several days ago and aph re-posted yesterday: N2338: Concurrency memory model compiler consequences. When the authors of the proposed memory model take the time to spell out how the issues affect compilers, you'd hope people would read it before pontificating on that very subject.

The discusion has spilled over to LKML and (among others) Ian Lance Taylor's blag, which has been required reading for me since his series on linkers.

Unfortunately, despite all the apparent experts on the GCC list arguing about whether particular examples are valid without locks or memory barriers, noone seems interested in reviewing my patch to improve the use of memory barriers in GCC's shared_ptr. Maybe it would get more attention if I argued from personal conviction and dogma rather than trying to write correctly synchronised code using the right barriers ;-)

mathrick: but it's just not very true, if you look past the rhetoric and expectations that everything works like Java. I wouldn't mind if it was funny, but the humour's uninspired too. Complaining that RAII forces you to use "smart pointers" (the derogatory quotes are his) but that built-in pointers aren't smart is fatuous, and the focus on smart pointers that manage memory (rather than, say, scoped mutex locks, or commit/rollback-style transactions) betrays his poor understanding of the idiom. C++ allows management of any resource using RAII-style library types. Java allows management of memory resources using builtin GC but has no automatic management of other resources. Personally I prefer general library solutions for any type of resource to builtin ones that only work with memory, but that's just a preference and I wouldn't expend so much energy comparing apples and oranges. The author implies that non-memory resources are rare anyway, giving files as an example. I wonder what the author writes if he doesn't need to use mutexes, database handles, sockets etc. let alone "non-system" resources. I'm currently using RAII to manage login sessions with a futures exchange, so that I know it will logout correctly when the session object goes out of scope, rather than just dropping the connection. Conflating RAII solely with memory management and then comparing it to garbage collected memory is a strawman.

I know noone except me reads compiler documentation anyway, but it's a shame that the libstdc++ docs tend not to turn up in web searches. It would be nice if e.g. gcc filebuf fd turned up the relevant docs, not just various posts to the mailing list.

Maybe this post will help.

pphaneuf, welcome to the world of Exception-Neutral code, i.e. code that works correctly when exceptions are present, but does not require them.

C++ exceptions make a hell of a lot more sense when you realise you shouldn't be handling them as close as possible to the throw site by covering your code in try-catch blocks. That defeats the point of separating the error-handling code and the "business logic."

Exception-neutral code is generally clearer and more expressive, and in many cases it's smaller and faster because all the destructor code is already there and will run anyway whether you leave the scope due to return or throw, but you don't have the overhead of a try-catch (the catch might involve a runtime type-identification check.)

I also find that code that aims to be exception-neutral is more likely to be correct, partly just because it's easier to reason about clearer, expressive code. Compare the various implementations of an assignment operator in the notes from my Exception Safety talk.

I've said it before and I'll say it again: destructors are my favourite C++ language feature. Without destructors you have no RAII, no exception-neutral code and automatic deterministic resource cleanup is an order of magnitude harder.

And yes, mysql++ misuses exceptions for flow-control in some places. I think Warren's planning API changes for version 3.0 so the point's worth raising on the mailing list.

Look as though renaming a blogspot blog causes the last diary entry to be re-posted to advogato. e.g. bkode: post, re-post and oubiwann: post, re-post (compare the syndicated ... from ... footnotes).

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