GCC is dead, long live the young LLVM

(Before I get flamed, I’m talking of course of GCC in the context of the toolchains provided by Apple for Mac and iOS development; the GCC project is still going strong, of course.)

You have no doubt noticed that GCC disappeared from the Mac OS X developer tools install starting with Lion; if you do gcc --version, you’ll see LLVM-GCC has been given the task of handling compilation duties for build systems that directly reference gcc. And now with the release of the iOS 5 SDK, GCC has been removed for iOS development too, leaving only LLVM-based compilers there as well.

Overall I’m going to say it’s a good thing: LLVM, especially with the Clang front end has already accomplished a lot, and yet has so much potential ahead of it; while GCC was not a liability, I guess this very customized fork was a bit high maintenance. Still, after 20 years of faithful service for Cocoa development at NeXT then Apple, it seems a bit cavalier for GCC to be expelled in mere months between the explicit announcement and it actually being removed. Ah well.

But while I have no worry with LLVM when doing desktop development (that is, when targeting x86 and x86-64), however LLVM targeting iOS (and thus ARM) is young. Very young. LLVM has only been deemed production quality when targeting ARM in summer 2010, merely one year ago and change. Since then I have heard of (and seen acknowledged by Chris Lattner) a fatal issue (since fixed) with LLVM for ARM, and it seems another has cropped up in Xcode 4.2 (hat tip to @chockenberry). So I think the decision to remove GCC as an option for iOS development was slightly premature on Apple’s part: a compiler is supposed to be something you can trust, as it has the potential to introduce bugs anywhere in your code; it has to be more reliable and trustworthy than the libraries, or even the kernel, as Peter Hosey quipped.

Now don’t get me wrong, I have no problem with using Clang or LLVM-GCC for iOS development, in fact at work we switched to Clang on a trial basis (I guess it’s now no longer on a trial basis anymore, certainly not after the iOS 5 SDK) about one year ago, and we’ve not had any issue ourselves nor looked back since. Indeed, for its relative lack of maturity and the incidents I mentioned, LLVM has one redeeming quality, and it’s overwhelming: Apple is itself using LLVM to compile iOS; Cocoa libraries, built-in apps, Apple iOS App Store apps, etc., millions upon millions of lines of code ensure that if a bug crops up in LLVM, Apple will see it before you do… provided, that is, that you don’t do things Apple doesn’t do. For instance, Apple has stopped targeting ARMv6 devices starting with iOS 4.3 in March 2011, and it is no coincidence that the two incidents I mentioned were confined to ARMv6 and did not affect ARMv7 compilation.

So I recommend a period of regency, where we allow LLVM to rule, but carefully oversee it, and in particular prevent it from doing anything it wouldn’t do at Apple, so that we remain squarely in the use cases where Apple shields us from trouble. This means:

  • foregoing ARMv6 development from now on. In this day and age it’s not outlandish to have new projects be ARMv7-only, so do so. If you need to maintain an existing app that has ARMv6 compatibility, then develop and build it for release with Xcode 4.1 and GCC, or better yet, on a Snow Leopard machine with Xcode 3.2.6 (or if you don’t mind Snow Leopard Server, it seems to be possible to use a virtual machine to do so).
  • avoiding unaligned accesses, especially for floating-point variables. It is always a good idea anyway, but doubly so now; doing otherwise is just asking for trouble.
  • ensuring your code is correct. That sounds like evident advice, but I’ve seen in some cases incorrect code which would run OK with GCC, but was broken by LLVM’s optimizations.
  • I’d even be wary of advanced C++ features; as anyone who has spent enough time in the iOS debugger can attest from the call stacks featuring C++ functions from the system, Apple uses quite a bit of C++ in the implementation of some frameworks, like Core Animation, however C++ is so vast that I’m not sure they make use of every nook and cranny of the C++98 specification, so be careful.
  • avoiding anything else you can think of that affects code generation and is unusual enough that Apple likely does not use it internally.

Now there’s no need to be paranoid either; for instance to the best of my knowledge Apple compiles most of its code for Thumb, but some is in ARM mode, so you shouldn’t have any problem coming from using one or the other.

With this regency in place until LLVM matures, there should be no problems ahead and only success with your iOS development (as far as compiling is concerned, of course…)