Friday 31 October 2008

C++: Restoring the meaning of a name

I have updated a previous blog entry about a C++ name-scope issue with a solution.

Thanks to the commenter jd who provided the solution.

A MacBook Pro hard drive upgrade

I have just upgraded my 15" Macbook Pro with a larger hard drive. The machine was shipped with a 120G hard drive when I bought it. Times move on, and data accumulates. Cubase projects and Parallels virtual machines quickly fill up precious space.

Hard drives are not a user-upgradable component of these notebook models, but there are plenty of descriptions of how to disassemble a MacBook Pro available on the net. To their credit, MacBook Pros are relatively easy to pull apart and very well-made machines. Still not as serviceable as an IBM (or Lenovo, or whatever they're called these days), but not bad at all.

The upgrade is perfectly simple for anyone with technical competence, a little bravery, and a torx size 6 screwdriver.

The drive

I installed a 320G Western Digital Scorpio drive, which seems a very good choice. It's a high-performance 7200RPM drive. WD claim that it consumes a comparable amount of power as an equivalent 5400RPM drive - a claim I can't validate this yet, except to say that battery life doesn't seem significantly shorter than with the previous drive.

A jump from 5400 to 7200RPM is great. The result is a snappier machine which handles better when running many tracks at once in Cubase. Software build speeds are marginally faster. The machine boots more quickly, too, but I tend to reboot infrequently anyway.

Running XBench tests before and after give compelling results:
  • Sequential uncached writes increase from 18.3MB/sec to 55.5MB/sec
  • Sequential uncached reads increase from 9.1MB/sec to 19.7MB/sec
  • Random uncached writes increase from 9.8MB/sec to 31.7MB/sec
  • Random uncached reads increase from 8.2MB/sec to 24.93MB/sec
Installation

The only interesting part of the process was working out how to migrate my old data onto the new drive.

Previously, I've performed a Leopard install with the old drive attached over USB; the Mac OS installer magically notices the old drive and offers to migrate the data over. I tried this. but it didn't go as planned - not all the data migrated over (a whole load of components and programs didn't move across) and the installer still forced me to register and add a new user, despite there being a number of users that had just migrated over. Less than full marks, then. I wonder whether this was due to the Leopard version on the old disk being ahead of the install DVD version?

There are suggestions that a Time Machine backup is a good migration strategy. But I fear that this will fail in pretty much the same way.

The solution is simple, though:
  • Boot the machine from the Leopard install disk.
  • Select Disk Utility from the Tools menu.
  • Partition the new drive with a suitable partition table to boot an Intel machine. Create a single journalled HFS+ partition.
  • Click on the "Restore" tab and restore data from the old drive (make the old drive the Source) onto the new drive (make the new drive the Destination).
  • Ensure that Erase desination checkbox is selected.
  • Click on OK.
  • The old data is copied onto the new drive's parition.
  • You now have a carbon copy of yor old drive, covering the entire surface of the new drive.

Friday 24 October 2008

C++: Changing the meaning of a name

We've just bumped the version of gcc we use to build our codebase from 4.2.2 to the shiny, cutting edge 4.3.2. This involved the usual number of small tweaks to our source, to make it compatible with the latest gcc parser.

One change surprised me, though. The following pattern is no longer accepted by gcc:
template <typename T>
class Producer
{
public:
/// ...
};

template <typename T>
class Consumer
{
public:
typedef Producer<T> Producer;
};

void ThisWontCompile()
{
Producer<int> producer;
Consumer<int> consumer;
}
gcc now generates the following error:
test.cpp:13: error: declaration of 'typedef class Producer Consumer::Producer'
test.cpp:4: error: changes meaning of 'Producer' from 'class Producer'
We use this pattern quite a lot in our code, and it seems reasonably tasteful. Certainly, it seems morally equivalent to the following pattern:
class Foo
{
public:
/// ...
};

class Bar
{
public:
void Foo() {}
};

void ThisCompiles()
{
Bar bar;
}
...in the sense that they both change the meaning of a name within the scope of the second class.

Now I'm no C++ language lawyer, but I've yet to find a compelling part of the standard that shows this to be bad C++ code.

Update

Commenter jd pointed out the solution to this conundrum. The Producer example above will compile if the typedef is written slightly differently, thus:
template <typename T>
class Producer
{
public:
/// ...
};

template <typename T>
class Consumer
{
public:
typedef ::Producer<T> Producer;
};

void ThisDoesCompile_Hurrah()
{
Producer<int> producer;
Consumer<int> consumer;
}
This shows that the gcc change was not as drastic as I first feared, and the fix is still very valid (and very readable) C++ code.

The problem was gcc looking up the name Producer in the scope of the Consumer class, and finding the Producer typedef name that was in the process of being defined. A subtle problem with a non entirely useful error message (but we're used to those, aren't we?).

Although the other compilers I have tried (MSVC and Comeau) accept the original code, I'm not sure if it is correct according to the letter of the C++ standard or not.

Tarballs, tarballs everywhere (or "More madness of glibc")

My previous posting on the packaging of GNU's glibc project seems to have created quite a stir (see here and here). There's been lots of informed, and some uninformed, debate on the subject.

The glibc project has taken the informed choice to abandon the traditional tarball method of source code release, instead directing developers to get the code from the project's CVS repository directly. Thankfully, following my earlier post, instructions have been put up on the public website so it's now clearer how to obtain the latest version of the glibc source from CVS. So my initial problem has now been solved. Thanks, guys!

Now, clearly this isn't the End Of The World. And any developer capable of working usefully with glibc should be more than competent enough to operate CVS themselves. So stop whinging and get over it... right?

Wrong.

The madness of CVS

Source code projects should always be developed using a Source Code Management system, like CVS (or Subversion, or perhaps a more modern, fashionable, distributed SCM like Bazaar). This is common sense. It's good practice. It's important. Each release should be managed in the SCM on a release branch, and public code drops should be recorded with tags (or labels). This is accepted release engineering practice.

However, downloading a source code release from CVS (or any other SCM) is a really poor distribution mechanism. Here's why:
  • It's not conventional. Unix source packages are traditionally distributed as tarballs (either tar.gz or tar.bz2 tarballs). It's the way the world works. Not providing tarballs forces users to work harder, and makes them less likely to use your code. However, this is not a compelling reason for glibc to distribute tarballs. Indeed, for glibc it's not even an issue. The project is important enough that people will do whatever is necessary to get the source. The glibc developers can distribute their code however they like. And I'll always say thank you.
  • It's not secure. Downloads sometimes go wrong. Unusual, but it can happen. Servers can also be hacked, and the code fiddled with. The accepted convention for this is to distribute MD5 checksums of the source tarballs that the downloader can use to ensure that their tarball is indeed the original. It's far easier to do this on a tarball than a CVS checkout (and there is currently no check mechanism for CVS exports from glibc). This is important, but is also not a compelling reason for glibc to distribute tarballs.
  • It's failable. By definition, the code in an SCM is dynamic. It changes over time. The codeline in the release branch changes as the release nears completion. True, the 2.7 relelase, and the 2.8 release and the 2.8.1 release can be individually tagged. However, these tags are dynamic. There is no guarantee that at a point some time after the 2.7 release, someone can't go back to the CVS repository and move the 2.7 release tag. The glibc 2.7 release could be different on Tuesday that it was on Monday! Sure, good developers shouldn't do that. But they might. By mistake or otherwise. In less capable SCM systems, like CVS, there is no way of usefully tracking the history of the tag. Release tags in CVS are not static. The only safe way to construct a stable, unchanging release snapshot of the code is to archive a tarball. Say, on an FTP site. This is a compelling reason not to download glibc source code releases from the project's CVS repository.
I believe that CVS access is simply not an acceptable release mechanism for the glibc, or for any other, project.

There has to be another way

Additionally, people have been pointing out third party ways to get glibc more easily, or to track its progress more easily, like an external gitweb interface. This is also not an acceptable solution for easily pulling glibc releases. As a developer who would like to use pure, unadulterated glibc source code release, I can only accept source code that I obtain directly from the glibc project themselves.

I know these third parties are trying to perform a useful service, and are doing this with the best intentions. But, unfortunately, I can only accept source code drops that come directly form the official project. Not from unverifiable third party mirrors, or from tarballs packaged by a third party (like Fedora - how can I be sure that over time they won't put their own Fedora-specific patches in their version of glibc?)

If these are useful services, the providers should join the hard working glibc team, and perform their packaging services under their umbrella as an official service.

Postscript

I have nothing against the glib developers, or the glibc project itself. I appreciate all of their hard work. I offer this as constructive feedback. And I particularly do not like personal abuse directed at individual people. They are all hard working, clever guys who benefit the community greatly. I hope that I give back to the community a fraction of what they have done!

Thursday 23 October 2008

On GIMP 2.6 and the Mac.

Not so long ago, version 2.6 of The GIMP (The Gnu Image Manipulation Package) came out. If you don't know the GIMP, think Photoshop but open source. Well, GNU actually, but that's a different bunfight...

Version 2.6 isn't massively different from the previous 2.4 versions, but has enough new stuff to be very interesting.

Since I'm mostly a card-carrying mac Weenie these days, I waited patiently for a 2.6 release to arrive. To no avail. Until very recently, there has been no official mention of a 2.6 release on the gimp download page.

So I did a little digging. The GIMP website used to point you to the Wilber Loves Apple pages. But that project has unfortunately nose-dived with an acrimonious ending. Shame, they did a great service for the Mac community.

But, fear not... it turns out there are a few other GIMP port projects for the Mac. (Let's not spoil things by complaining that there should be just the one port, and it should be under the auspices of the actual GIMP project proper):
  • Gimp.app has existed for some time, but when I investigated, it's 2.6 port was still considered very experimental, and that doesn't inspire me with confidence.
  • MacPorts provides a way to build The GIMP from source. But unless you want to commit to the MacPorts world this is a somewhat heavy-handed way to get The GIMP. And the average graphic weenie doesn't have the technical nonse to do this. (Let's not consider whether the average graphic weenie would be using The GIMP in the first place).
  • MacGimp either doesn't exist any more (I can't get the website to load) or is commercial - which kinda defeats the purpose of using The GIMP.
  • gimponosx appears to be the new kid on the block, started by the main contributor to the Wilber Loves Apple project. They've produced a 2.6 release that appears (as far as I can see) to be perfectly stable and works as well as the previous ports. I've used it under Leopard on PPC and Intel machines. Go get it now if you like The Gimp!
Postscript: The GIMP download pages on a mac now point you to the gimponosx packages, so they have become the de-facto Mac GIMP port.

And whilst you're downloading, do yourself a favour and get an up-to-date version of X for Mac OS. It makes a huge difference.

Wednesday 22 October 2008

Book review: Extended STL

Details
Title: Extended STL Volume 1
Author: Matthew Wilson
Publisher: Addison-Wesley 2007
Pages: 572
ISBN: 978-0-321-30550-3
Links amazon | publisher
The prologue

This is an unusual book review for me. Normally, I digest a technical book in a matter of a week or two and then write a review. I don't like writing a review without having fully read the entire contents of a book; it's not a fair and representative review. Consequently this review is remarkably delayed as Extended STL has taken me literally months to read.

Why is this? The information in this book is dense and not easily digested. There's a lot of complex stuff in here that - especially in order to review fully - you really have to pay attention to. I'm not sure I can entirely blame this on the book, though. It's a natural consequence of the subject material.

What's it about?

Extended C++ is the first volume in Wilson's projected two part series. This tome covers collections and iterators. That is, it describes how to create STL-compliant containers and iterators from scratch or how to wrap existing pieces of code with STL-interfacable proxies. This is a non-trivial area, with many subtle problems. The meat of the book is an in-depth description of problems and solutions in the implementation of STL-like code.

Volume 2 of the series will cover (amongst other things) STL-like functions, algorithms, adaptors and allocators. No doubt that, too, will be a dense book covering complex subject matter.

Extended C++ is a fairly unusual book in the current marketplace, and so has little competition. There are many books on learning or using C++, on good C++ style, and on C++ programming idioms. There are many books describing particular C++ libraries. But there are few specifically about writing STL-like extensions, and interfacing existing code with the STL. So there's little competition for Extended C++. If you are doing this kind of stuff then the book looks like a sound investment.

So is it any good?

This book is not an easy read. It took me an incredibly long time to complete; it's not easy to read in small chunks, or when you brain is full of other stuff. You really have to study a chapter in depth from start to finish to follow the flow.

Extended C++ opens with a set of chapters on foundational concepts and terminology. These are a refresher in some important C++ STL-related techniques, and I suspect that the majority readers will take away the most useful stuff from these chapters alone!

The chapters in the subsequent two parts (collections first, then iterators) usually cover a single example of the implementation of a STL-like component: explaining the reason for writing the component, the problems discovered during implementation, and the ultimate solution. An included CD contains all the numerous code examples in the book.

Sometimes this example-driven approach makes it hard to determine the most important information presented in chapter. It also makes Extended C++ less than ideal as a reference-work to look techniques up in.

The book contains a scattering of "tips" in callout boxes. These appear to be a rather inconsistently applied narrative conceit. They should either have been scrapped or rationalised significantly.

As you read the text, it's clear that you are getting information from someone who really knows what he's talking about, and who has done a lot of this kind of legwork many times over. Wilson's writing style is clear although sometimes I wonder whether the information could have been presented better in a different structure.

Extended C++ is a testament to the incredible power and to the incredible complexity of the language. Many of C++'s detractors could cite it as a counter-example for use of the language!

I found very few technical problems or mistakes in the text. If I was being picky, I'd criticise the author's propensity for somewhat flowery language which will leave non-native (and some native) English speakers confused (or reaching for the dictionary).

Summary

Pros
  • Fairly unique coverage of this aspect of C++ coding
  • Clear writing style
  • The voice of an expert
Cons
  • Dense information, often hard to digest
  • Not ideal as a reference work
Recommended if you are writing STL-like C++ code, or want to interface legacy code with STL-style C++. Make sure you have plenty of time to sit down and digest the material, though.

Friday 17 October 2008

The madness of glibc

Great. Something else for me to have a techie moan about. It's not as if I have any actual work to do, is it?

We build devices that run Linux. We make our Linux environment from scratch, so we have an in-house routine of building binutils, gcc, glibc, busybox, and so on. It's standard stuff for those used to the joys of getting Linux built from scatch.

Summary: it's embarrassingly hard to build Linux from scratch. Everything needs a bit of gentle bodging to work. If you change one component of the Linux build chain, it's odds-on that you'll have to tinker with many others.

That's just life. Programming was never supposed to be easy, was it? But you don't want people to make the job any harder than it has to be.

So helpfully, in these enlightened times, the glibc release dudes now no longer supply tarballs of their source releases. And they don't really tell you that they don't either.

Sigh.

Here are the details...

Everything old is new again

The glibc homepage is here: http://www.gnu.org/software/libc
  • The "Current status" section says that the latest version is 2.8
  • The "Availability" section says that releases are available from the GNU FTP site (http://ftp.gnu.org/gnu/glibc/)
  • The latest version available there is 2.7
  • There are no other hints or bits of documentation about this
I have a habit of just hitting the FTP site, and pulling down the latest revision posted there. So it took a long time and a lot of manual fixing of the (old) 2.7 release before I realised that I was working with an archaic version.

So what's any geek to do? I hit Google. And here's what I discovered:

Finding the truth

http://sourceware.org/ml/libc-alpha/2008-05/msg00074.html shows a mailing list post from the glibc maintainer which states that:
Tarballs are a completely outdated concept.
And he refused to package glibc releases any more. Go get it from CVS yourself. Crumbs!

Helpfully, he's not only not packaging releases, he's also not telling people how to get them easily. And he's not making it clear that the FTP site is now NOT the source of the latest releases.

There is some well reasoned comment to this (including http://sourceware.org/ml/libc-alpha/2008-05/msg00076.html) highlighting the advantages of packaged source releases. Still, that's not my choice, and I can't help it.

So how do you get it?

The glibc resources page (http://www.gnu.org/software/libc/resources.html) describes the location of the project's CVS repository, and how to get sources from it via annonymous pserver access. However, there's no mention of the release tag you need to get a release.

So it's up to you, luck, and the raw power of CVS. This was a culture shock for me; it's been years since I last used CVS! And my finger memory won't even allow me to type cvs. Every time I tried typing it, it came out 'svn')

Helpfully you can't even "cvs ls" the repository as the server does not support "ls". Good start.

A bit of digging in the glibc CVSweb interface helped me to discover the tag was called glibc-2_8 and that the two modules I needed to check out were called "libc" and "ports"

Since our build system requires the traditional glibc and glibs-ports
tarballs as input to the build process, I needed to recreate some tarballs, even if they are not official release sets.

The script below is how to do this, for those in a similar predicament.

Later I found http://sourceware.org/glibc/ which is another (unofficial) glibc homepage that has slightly more info on it. However, it still doesn't tell you the release tag for the latest source release. Sigh.

Whinge, whinge, whinge

So what? I can hardly complain can I? I can't demand a refund for this shocking lack of unpaid support for the free software I'm using without cost? So I'll just have to have a bloggy moan about it instead.

RELEASE_TAG=glibc-2_8
VERSION=2.8

cvs -z 9 -d :pserver:anoncvs@sources.redhat.com:/cvs/glibc login
cvs -z 9 -d :pserver:anoncvs@sources.redhat.com:/cvs/glibc export -r $RELEASE_TAG libc
cvs -z 9 -d :pserver:anoncvs@sources.redhat.com:/cvs/glibc export -r $RELEASE_TAG ports
mv ports/ glibc-ports-$VERSION
mv libc/ glibc-$VERSION
tar cfj glibc-ports-$VERSION.tar.bz2 glibc-ports-$VERSION
tar cfj glibc-$VERSION.tar.bz2 glibc-$VERSION

Thursday 16 October 2008

Overload 87

The excellent Overload magazine's issue 87 is out now, available from ACCU.

Enjoy the cover artwork - another of my productions.

Friday 10 October 2008

Book review: Beginning Xcode


Details
Book: Beginning Xcode
Author: James Bucanek
Publisher: Wrox 2006
ISBN: 978-0-471-75479-4
Pages: 590
Links: Amazon | Publisher
This book is way old now. It covers Xcode version 2.2, which is so far behind the cutting edge it's practically blunt. It's two years old, which is about 100 years in the tech book world. So why am I bothering to post a review of such a book? Simply, because I found it useful, and it's worth doing it justice here.

Previously, I reviewed Xcode Unleashed (published by SAMS) and found it good but not perfect. I obtained this book at the same time, and it turned out to be a great compliment. Whereas Xcode Unleashed was a rapid trip through Xcode, this book walks at a more lesuirely and detailed pace. It filled in holes in my understanding left from Xcode Unleashed.

Sometimes, it was a little too lesuirely (I didn't really need 55 pages on the basic operation of the code editor, for example). But you can't fault the detail.

The author writes clearly, and the layout is not fussy, contributing well to the book. Bucanek describes the basic operation of Xcode, its projects and group/target principles, describes editing and managing items within Xcode, and the processes you'd expect: developing code, interfaces, building, debugging, profiling, and unit testing.

Although Xcode has matured considerably since version 2.2, very little of the information in this tome is stale or factually incorrect. Some of the newer profiling and analysis tools will inevitably not be covered, but all the basics are there. I wonder whether the author is working on a revision for 2009?

Summary

Pros:
  • Comprehensive and detailed
  • Clear writing
Cons:
  • Old; it covers a rather old version of Xcode
A good, thorough, if old, book on Xcode developement. Suitable for complete novices to Apple development.

Recommended if you don't pay too much for it.

Monday 6 October 2008

Breathe 2008 (the aftermath)

Phew! What a weekend...

From Friday through to Sunday I was playing keyboards at C3's awesome Breathe conference, at the Corn Exchange in Cambridge. It's a great venue to play, and it's nice to play on a much larger stage than usual. The band were excellent, and it was great fun to spend the entire weekend playing together, although very hard work.

During the event I had a very weird experience: In December last year, I had my bike stolen from outside my house. On Saturday I strolled into an enclosed service area out the back of the Corn Exchange, and what do you think I found? My stolen bike. A little worse for wear, but happily leaning against a wall.