Tuesday, 9 September 2008

Article: Idioms and Idiosyncrasies

The latest issue of Better Software magazine is out now, and I've written this month's Code Craft column. (And yes, it is a huge coincidence that the column has the same name as my book!) (Aside: I have no idea why Amazon continually switches between the right cover image for the book and an incorrect one. Flipping technology).

Here's the synopsis:
As programmers, we are not merely engineering drones; we are also artisans. The act of programming involves as much artistry as it does technicality. When we craft great software, we naturally use language idioms help to show the elegance, beauty, and artistry of a piece of code. But sometimes the desire for beautiful idiomatic code can trip us up.
You can read it online here.

Monday, 8 September 2008

Cubase 4.5

A surprise present awaited me on return from my holiday: Steinberg have released a new free minor update to my DAW of choice, Cubase. I've always foolishly updated Cubase immediately before finding out problems from early adopters on the forums. New shiney things! Must have! Now!

So is it any good? Yes, thankfully.

Here are my initial impressions:
  • It's no more buggy than before, as far as I can see. Well, that's a start. But it gets better...
  • Support for adding/removing audio interfaces whilst Cubase is open has returned on the Mac!!! Hurrah!!! I cannot say how cross I was when this feature silently disappeared in a Cubase update (somewhere around 4.1 or so). When using my MacBook Pro, I'm always flitting between audio interfaces: I have two firewire devices in my studio at home, another at work, and a USB interface for on the road. Sometimes, I'll also just use the internal mic/speakers for a quick noodle. A desktop installation clearly doesn't suffer this problem, but having to shut down and restart Cubase every time I wanted to use a new audio interface (often) was a real drag. They've fixed it. Steinberg, I love you!!!
  • It uses more CPU than the previous version. This is actually a real bummer, but is (thankfully) offset by the previous bonus point (for me).
  • MP3 export has been fixed - it can now write ID3 tags correctly, so I don't have to resort to a third party tagging program after export.
  • The new Yamaha S90ES piano is a very cute addition. I'm a keyboard player, so this really does it for me. I use a Roland stage piano live, and so now I can look smug at my Yamaha S90ES owning co-band-member. I've got his piano sound too :-) However, I have to be honest: I prefer the sound of the TruePianos plugin that I use. The Saphire module just does it for me, and their new Amber is also great. So I'm not sure that I'll end up using the Yamaha all that much. (However, if I'd had the Yamaha from the start maybe I'd not have bothered with another Piano plugin. Who knows?)
  • New drum loops. Whatever. They'll float someone's boat.
  • New sounds. The guitars are OK. The basses are pants. There's some other stuff, but nothing as impressive as the Yamaha grand.
  • VST3 Sound. It's a low-level thing. You wouldn't notice it as a user. There's no interface change to the MediaBay. You won't until (unless) other VST manufacturers start supporting it.

Friday, 5 September 2008

The trials and tribulations of Boost 1.36.0

I've been updating the toolchain that we use to build our products recently; we've upgraded to a much newer Linux kernel and use an (almost) up-to-date gcc that generates much better ARM code. Woo hoo!

Whilst I was at it, I decided to upgrade some of the third party libraries we depend on. I updated to Boost 1.35.0 (which was the latest version available when I started), and got the ARM build working successfully (some of our source code had to be modified for the new library version, mostly around boost::filesystem and boost::thread).

Since Boost 1.36.0 has recently been released, I thought it would be worth moving up another 0.1 worth of code and using that before I took the new toolchain live. It aparently has bugfixes around the threading code. Sounds useful. But oh, the best-laid plans of mice and men often go awry...

Sigh.

I have suffered two nasty Boost-related problemettes that I will share with you, gentle reader. One, to be fair is not just 1.36.0's fault...

1. shared_ptr with posix threads locks up on x86 platforms

It's easy enough to say it, but it took me a while to work out what was going wrong.

Since we target ARM devices, and ARMs do not have an atomic increment/fetch (which boost::shared_ptr relies on) we have to build it with a Posix thread library shared_count backend (by forcing -DBOOST_SP_USE_PTHREADS through to the compile using evil bjam config foo).

We also run our code on local x86 development machines for convenience (and to run our unit tests locally). To ensure the execution environment is as similar as on the target machine, I've always configured Boost to use posix locks around shared_count on this platform, too. It made sense. And it worked fine on 1.34.x versions.

However, on 1.36.o (and, as it happens, on 1.35.0, too - but I only discovered that later), that combination does not work. At least with gcc 4.2.2 and gcc 4.2.3.

Any boost::thread object you create fails to start, and wedges the calling thread. (Internally, the boost::thread::start_thread method in the posix implementation attempts to assign a shared_ptr variable, which causes a deadlock around the shared_count's pthread_mutex_lock call. I don't understand how or why that would fail; there appears to be no way that mutex would be used elsewhere. But there it is; it locks up. I am wondering about random comsic rays or, more likely, a compiler bug: If you disable compiler optimisations the deadlock magically disappears (which makes stepping through the code in gdb to find out what the problem is... tricky).

Solution #1: don't configure boost with -DBOOST_SP_USE_PTHREADS on Intel machines.

2. ARM builds of boost 1.36.0 will not link.

Blasted thing. I finally got the codebase to compile against the 1.36.0 verison of boost and would it link? No it would not. It gave up with lots of bitching about __sync_add_and_fetch_4. This is a glibc internal function that is not supported on ARM platforms (the ARM instruction set does not make such an operation supportable).

Now, I've stared at this problem for a reasonable length of time, and I can't actually see which bit of the Boost codebase is (directly or indirectly) pulling in a reference to this symbol. But it is. And it shouldn't be. For the time being, this problem has beaten me.

At the moment, I have to get the toolchain live rather than waste more precious developer hours, so I've regressed back to Boost 1.35.0 which does not suffer this linkage problem.

Solution #2: Do not use boost 1.36.0. (Yet.)

Sigh.

I hope this whittering blog entry will help other people who get stuck in similar predicaments.

The incomparable joy of C++ inner classes

More on my love/hate relationship with my programming tool of choice. Oh C++. Oh joy. Literally incomparable joy. Because I discovered that you can't easily compare inner classes if the outer class is a template.

You say what?

OK, take a look at this code...

#include <cassert>

template <typename T>
struct outer
{
class inner;
};

template <typename T>
struct outer::inner
{
inner(const T &a) : a(a) {}

const T a;

//With this uncommented, we find an operator== in main [1]
//bool operator==(const inner &other)
//{ return other.a == a; }
};

// This operator== is never found
template <typename T>
bool operator==(const typename outer::inner &lhs,
const typename outer::inner &rhs)
{
return lhs.a == rhs.a;
}


int main()
{
outer::inner a(10);
outer::inner b(20);

// So this doesn't compile
assert(a == a);
assert(b == b);
assert(!(a == b));
}
I naively expected that to work OK. On gcc 4.x it generates this error:

> g++ test.cpp && ./a.out
test.cpp: In function ‘int main()’:
test.cpp:35: error: no match for ‘operator==’ in ‘a == a’
test.cpp:36: error: no match for ‘operator==’ in ‘b == b’
test.cpp:37: error: no match for ‘operator==’ in ‘a == b’
If you add in the code marked as [1], an operator== is found and all is well. However, there is more flexibility in the second operator== form, and I need to be able to write one. Game over.

This is a case of a classic template problem, where the compiler cannot deduce template type of an outer class based on the inner type - a non-deduced context where the compiler is
not required to figure out what Ts would produce a match for your
inner class. To be fair, that would be rather heroic for it to figure out.

The most workable solution I can find is to move the inner class out to a separate top-level template class. This has the downside that it pollutes the enclosing namespace with detail that needn't actually be there. But it has the advantage of generating code that works, and so I can live with that.

template <typename T>
struct outer_inner
{

T a;
};

template <typename T>
bool operator==(outer_inner const& lhs, outer_inner const& rhs)
{
return lhs.a == rhs.a
}

template <typename T>
struct outer
{

typedef outer_inner inner;
};
As a compromise, I am tempted to make a "details" namespace, just to put the morally "inner" top-level classes in, so that the top-level is (relatively) unpolluted.

Why do I care about this? I'm implementing an STL-like container (more on this another time). If outer was instead spelt std::map, and inner was spelt iterator, then you can begin to see my motivation.

Thursday, 21 August 2008

The voiceover artist.

I've just noticed that some of my voiceover work is available online. Check out the DDS80 video on the Numark website here (click on Video under the pictures to see it). This is one of the products I've been working on for Numark recently.

I originally made these voiceovers for an on-the-product demo display I made a day or two before a trade show. Apparently, my quaint British accent went down really well. So they used the same voiceovers for the video.

I recorded these with my Red 5 condenser mic; highly recommended.

Monday, 18 August 2008

Article: Restaurant C++ and pidgin Python

The latest column in my Professionalism in Programming series is available now in the August issue of ACCU's C Vu magazine. Find out more about it here.

Building in Uganda

We're now most definitely back from building in Uganda. (We've been back for a few days now, but falling back into 'real life' is hard work, and I've only just had time to surface for air!).

What an experience it was.
Check it out here:
  • There's a short video describing the project and the trip on YouTube here...


  • A small selection photos of the work we did are available on Facebook here.
Nine people from C3 went out on a two-week mission trip, to build part of a student house in the Suubi Watoto village. The build was extremely successful, and the team worked together really well.

It's really hard to put the trip into words; the whole thing was truly a life-changing experience. We saw the good and the bad in Uganda. The country is developing fast, recovering from a legacy of brutal dictators and a devastating aids epidemic. An estimated two million children have been left orphaned, 880,000 as a result of aids alone. Those are frightening statistics.

We witnessed the poverty and awful conditions that so many Ugandan children live in - seeing children living in ditches beside the Kampala railway lines was a moving experience. And in contrast to this, we saw the incredible change that Watoto is making in children's lives: seeing them plucked from the gutter (in many cases, quite literally) and given joy, a family, a house, an education. It's radical social action, making a real difference in these children's lives.

It was awesome to see the scope and quality of the work being done at Watoto, and a privilege to be able be a part of the project. They are currently running three villages. A fourth is being built right now in Gulu - in the aftermath of the bloody Ugandan civil war in those northern territories. It will minister to the thousands of children who have been enlisted as child soldiers, or child prostitutes.

Check out more about Watoto here.