Macintosh

There are 53 entries in this Category.

Why I don't want to be Delicious – Beyond the Unboxing Experience

Ages ago, most blogs I read were abuzz with talk about “the delicious generation”. There was talk about “writing your own fucking HIG”, about “steak versus sizzle”, and many other beautiful and colourful phrases summarizing why and what the “Delicious” group of applications was (supposed to be).

Let’s just say that I always felt uncomfortable about the whole concept. Maybe it is because I started programming under classic MacOS, where Human Interface Guidelines were strict, and we had to count every pixel twice before using it for a UI element. Pixels were rare, and colors were few and far between. We had to walk ten miles, uphill, barefoot in the snow just to get an event loop, and even then we had to write it ourselves. And when our app crashed, it took the Mac with it, and we liked it that way. … err … sorry, don’t know where that came from.

All right, I admit there are some things the delicious apps, and their stepchildren, and Apple’s UI experiments in their own mothership-designed apps have given us that I am very grateful for, and which I appreciate:

  • A whack over the head reminding us that we have enough colors and pixels these days that we can use a different texture for a popup button without the risk that no user will recognize it as a popup button.
  • A renaissance of real-world metaphors, but this time in photorealism instead of as the simplified, idealized toys in MacDraw’s and MacPaint’s toolboxes.
  • A new appreciation of professional graphics design and polish.
  • More attention paid to the un-boxing experience and to welcoming new users, including the metaphorical return of the trusted old “Macintosh Intro” and “HyperCard Tour” in the form of welcome screens and tutorial screencasts built right into the applications.
  • Heart and soul for our applications, including tiny features that make our users go “wow!” when they realize someone actually thought of that.
  • A willingness to part from the well-trodden paths of the letter of the Human Interface Guidelines when there is a good, well-researched reason to do so, and it doesn’t violate its spirit.

However, one thing I found consistently missing, was paying attention to users’ workflows and efficiency. Most of the attention seemed to have been paid to the initial un-boxing, leading the user into the application, making them go “wow!”, providing the basic feature set that was needed to sell an application as whatever kind of application it was supposed to be.

File comparison utilities that were only able to compare two files, without the ability to take into account a common ancestor (heck … FileMerge and even diff do that out of the box, for free!). Version control applications that require you to select every single file and add it, are unable to retroactively detect moved files, have no support at all for branches and merging, and hence get their asses kicked by an application with an Eclipse-style Java UI. Disk burning applications that made it too easy to accidentally delete a file while scrolling, and that just passed through features of the disk recording framework, and which haven’t seen more than a single maintenance update in over two years because they are apparently waiting for Apple to add new features instead of doing it themselves. Book databases that crawled to a halt just around the number of items where it would make sense to start keeping a database of them, and then sold the fix to that issue as a major reason for version 2.0.

All of these applications have one thing in common: They seem great at first, but after you’ve used them for a while, they fall down flat on their noses. Yes, not everybody uses an application the same way, and yes, not everyone needs the same features, and yes, you need to build up recognition and a brand identity if you want people to remember your application and you want to stay in business. But you also need to actually do for the user what she expects you to do.

And that’s why I have decided I do not want to be Delicious.

Do I want a professional-looking, polished application? Yes. Do I want to create a program that is inviting and enticing to the user? Yes. Do I want to provide the best, most intuitive user interface for my users? Hell yeah.

But my application also has to be able to support the user in doing their tasks every single day. It has to cope with the user not quitting it and not shutting down their Mac for a month or more on end. It has to honour their priorities and their data, it has to perform well in real-life situations with real-life data. It shouldn’t present cryptic error messages or get stuck in error message loops when an error occurs, and the concept of an “unexpected” error should be anathema. And it should support the user, not just sit by and be idly manipulated. It should have sensible defaults and do the right thing out-of-the-box.

And sure as hell it shouldn’t unnecessarily transmit the user’s data over the web or evaluate it just so I can present it on a map or announce how much money people have made using my app in the last month (!), redirect every operation on the ‘net the users do through my company servers, delete the user’s home folder or encrypt their files when my app thinks their license had been tampered with, send their whole address book to my company servers unencrypted without telling them beforehand, or install code that gets loaded into every application just so I get better crash reports.

Could a Delicious application get that right? Sure. Did any of them? Not that I’ve seen so far. With most of these apps, the graphic designer was driving the bandwagon. The arrangement of things on screen was not decided by how quickly a user can execute several operations that are usually done in sequence. It wasn’t decided by how easily the eye can grasp which screen elements go together, what relationship they have, or what the current state of the user’s data is. The driving design force seemed to be: Will it be a good demo? or Does it look good?.

Now, if you’ve paid attention to usability, the commonly-used term is rarely “look”. It is usually “look and feel”. And the feel is the domain of the interaction designer. And as much as I’d love to say otherwise, the “feel” rarely is delicious. The feel is that gossamer-thin fleeting quality that, after more than twenty years of aping, Windows still hasn’t been able to imitate from the Mac, and that the Mac invented without any help from its grandparents at Xerox PARC. The right feel is the thing to strive for, the feeling that the computer is along for the ride with you, the user, that the application is really there to help you, and is a reliable pillar of support, and not just a colourful banner flying in the wind.

Keynote, iMovie, iTunes and Garage Band, Apple’s apps that were so obviously the inspiration for some of the UI experiments that the delicious generation entertained, got this right. They made things as simple as possible, but no simpler. Did they make a few mis-steps? Yes, Keynote’s “Builds” drawer shamefully hides behind the inspector, waiting to be replaced with a timeline or something similarly easy to manipulate that doesn’t cause a huge bunch of stacked up objects in the middle of your window, but the custom UI in Garage Band made it look approachable, frendly, and that weird wooden edge gives it a real feel. And Keynote’s simplicity isn’t achieved by leaving out text labels and hoping your icon designer is a genius and can cram a complex context into an 8×8 pixel icon badge.

So, think different. Don’t do what the cool kids do. Be Non-Delicious and instead just create applications your users love.

In the interest of full disclosure, I should mention that I occasionally do work for Roxio on Toast, so my comments on disk-burning software may be biased. Then again, this is my personal blog. Everything I write is biased.

Porting to the Macintosh

It comes up a lot on the mailing lists, so I thought I’d write a little piece on the best approach to port an application from another platform (like Windows or a Linux) to the Macintosh. I won’t go into much detail, but outline the general way and the most common pitfalls.

Do not use Carbon or Cocoa-Java

Apple has, for historical and political reasons, provided several different programming APIs. One of them is Carbon, which is a C-based API that many cross-platform developers want to use because it’s more like MFC and other frameworks they already know. At this year’s Worldwide Developers’ Conference (WWDC) a long-running fight inside Apple finally came to a close, and Apple effectively announced they were killing Carbon. There is still some old documentation up on Apple’s developer web site that says otherwise, but don’t let that fool you.

If you are just getting started programming the Mac, use Cocoa to write your end-user application with a graphical user interface. A few of Carbon’s prettiest cherries have been “rescued”, but look for a Cocoa solution first. In particular, any GUI code written in Carbon (control manager, HIToolbox) is not a good investment of your time at this point.

There are also a number of bridges that allow you to use Cocoa with other languages. They’re a great technology, but most of them are fairly new, and you will face issues. Also, since they map Cocoa/Objective C concepts to another language, there will always be something lost in the translation. You will have to know how Objective C does things to understand these oddities. So why not go for Objective C in the first place, where Apple spends its main effort? All the documentation is for Objective C, too.

Don’t even try to use the Cocoa-Java bridge. Apple has already made clear it will see no more development.

You can use C++ with Cocoa

Many people think they will have to rewrite their application in Objective C to make it use Cocoa. That’s not true. Apple has taken great care to make it possible to mix Objective C and C++ in a project. The key here is the “Objective C++ compiler”, which is part of Xcode. You will still have to write the Mac-specific parts in Objective C, but the rest of your application can stay in C++ and can be easily shared with your Windows or Linux developers.

Don’t be afraid of Objective C, Objective C is essentially C: It has a few simple extensions to the language, which are quickly learned. These extensions may seem like a fancy way of duplicating C++ just for the heck of it, but actually, they’re completely different. Objective C essentially is a very elegant and simple way of wrapping the features of COM or CORBA, Qt’s preprocessor, and many other neat things that are done separately on many other platforms. Moreover, the Cocoa frameworks have been designed with Objective C’s particular strengths and weaknesses in mind. Porting Cocoa to C++ would result in such an ugly mess of nested template code you wouldn’t want to do it.

There is no MFC on the Mac

If you’ve never before ported an application to another platform (and I don’t count Windows CE as a different platform than desktop Win32), don’t think you can just look at each function and map it to “the Mac equivalent”. Each platform has been designed at a different time, and thus incorporated the currently accepted programming practices. To create a usable application, you will have to do things the way they are intended to be done on a particular platform. For the Mac, this means making sure your application is split up into a model-, a view- and a controller-layer, according to the MVC design pattern. This is not a Mac-ism: It is a standard design pattern listed in the GOF book, and commonly accepted as the best way to structure a cross-platform application.

If you find that something seems impossibly hard to do in Cocoa, chances are that you’re doing something that you’re either not supposed to be doing, or that you are supposed to be doing in a completely different way. The benefit of this is that you will find yourself being boosted by the framework in ways you didn’t think possible, instead of finding yourself fighting it every step of the way.

Cross-platform frameworks

There are frameworks that have been designed to sit on top of a platform’s native frameworks and hide away the details, for example Qt, Quaqua or wxWidgets. In short: If you aren’t porting a game, where all user interface is custom and you’re full screen without a menu bar anyway, don’t do it. Most of these frameworks don’t really behave like Mac users expect them to. Menus look subtly wrong, don’t scroll and don’t indicate overflows correctly. Keyboard shortcuts don’t work as expected. Pushbuttons are used with the wrong style, disabled icons look black-and-white instead of faded out…

The long story: There are ways to make them work, but in the end, you can’t really share much code regarding UI behaviour, so you might as well go fully native on each platform. Most cross-platform toolkits get the look and the basic behaviour right, but at some point fall into an uncanny valley where they frustrate Mac users. However, of course you can wrap the Mac’s drawing APIs to share code for some of your custom views and displays.

Resources for Mac programmers

I already mentioned Apple’s developer web site above, which contains a lot of resources. In particular, you can find documentation, sample code etc. there. A lot of this stuff gets automatically installed on your Mac when you install the Xcode tools (in /Developer/Examples you’ll get a lot of the sample code, though not all of it, and the documentation can be found in Xcode’s Help menu, and it will automatically download the newest version periodically).

There is a whole section on porting from other platforms on Appe’s developer web site. Just keep in mind that anything suggesting Carbon is probably outdated.

Apple also runs a bunch of mailing lists for developers. These are mainly a place to meet other developers, and are not an official support channel. Nonetheless, make sure you post on the right list: Many people post Cocoa questions on the Objective-C mailing list, which is mainly about the language itself and the language standard, and rarely the one you want to post on as a Mac developer.

Finally, if you find issues, use Apple’s bug reporter, also known as RADAR. You need a free “ADC Online” account, but that’s just so you don’t have to enter your info twice. You can use the same account in Apple’s store and iTunes, BTW. Do not post your bug reports to the mailing lists. You can ask if someone has found a workaround, but the mailing lists aren’t an official bug report channel, and unless you bother filing a bug, Apple will just think you’re venting and it’s not important enough, and will focus on the bugs somebody actually filed and thus indicated they matter to them.

Across-the-Room GUI

 

[Demonstration of a small progress bar and a large one at 100% and at the smaller size as seen from across the room]One important aspect of interaction design is determining typical usage patterns for your application. What many people overlook here, is that these patterns don’t just happen inside your application, but may also be influenced by what happens outside, in the real world, in the user’s home. As an example, let’s take a feature that a friend of mine implemented in Toast 8:

As you are no doubt aware, Toast is a disc burning application. Most of the user interaction here is pretty straightforward: You drag files into a window, and then click a button to burn the disc. And this point is exactly where it gets complicated: when you burn a disc, your computer gets busy. Not only does it have to encode video content if you are burning a DVD, and decode the original data. After that it also has to write all that data that that was generated to a silver disc.

A lot of data is moved around during this, and you do not want to put additional strain on your machine, for fear of causing the CD drive to run out of data and creating a coaster. Of course, there is buffer underrun protection, but if your Mac starts thrashing, your backup CD could still become a coaster. So what many people do, is just leave the computer alone for a while and go to the other end of the room to do something else.

Knowing that the user does that is what gives you an opportunity to create a better user experience: Imagine the user is, for example, vacuuming the room, or cooking lunch, or reading a book. They will occasionally glance at the computer display, to determine whether disc burning has finished.

Now, today’s progress bars are roughly 16 pixels tall. Not really suitable for reading from across the room. Furthermore, when the window isn’t frontmost, progress bars actually turn a pale gray and become slightly transparent. This makes it a lot harder to read to them from a distance, since pale gray and the white of the track merge into the background. So, what my friend did for Toast, was to create a custom progress bar control that was not only bigger and had stronger colors when inactive, but also showed different colors for the different phases of progress.

This not only made it easy for the user to spot the progress bar from across the room, it also made it obvious whether Toast was currently verifying the disc, or whether it was still writing the lead-in or whether it was actually in the process of burning a particular track.

[Toast 9's scross-the-room progress bar close up and at a distance]

As with any custom user interface, one has to be very careful here. There is a reason why progress bars turn pale in the background: all of the user interface is designed so that color and strong lines will draw you to the current, focused window first. Since Toast actually needs color to make the current phase obvious from across the room, it was decided to not have an animation in the progress bar, which would otherwise have overwhelmed the user interface while the user is sitting in front of the machine.

From what I have heard, this feature has been welcomed by the overall user community. Many of the professional users seem to be starting a burn job on one machine and then continuing to work on another.

I recently came across a backup application that not only used a small progress bar, but also had it on a blue surface. This didn’t just interfere with the partly transparent progress bar in a background window, it also made it hard to distinguish the blue background from the blue part of the progress bar. It was hard to see where the bar started and ended, only the little white “unfinished” area was still clearly visible.

I sent the developer an e-mail with a suggestion for fixing this. If you are a developer, I encourage you to look at your progress bars. If any of them shows for a longer time, it might be a good idea to ensure that it can be read more easily from across the room. You don’t have to go as far as the Toast developers went, but simply choosing the bigger progress bar size in Interface Builder, and making sure there is enough white space around the progress bar that it can easily be spotted, and its edges can easily be made out from a distance, would already help.

Custom Elements on WebKit Pages

Recently, I wanted to create a simple HTML editor. basically, I just wanted to WYSIWYG-edit styled text, and maybe insert a few images. But, of course there was one reason I could not use one of the existing HTML editors:

I needed to be able to insert special placeholder items. Little boxes, that could be double clicked for editing, and would otherwise just be part of the text like a regular character. In the final output, these would expand to special commands in a server-side scripting language, but I didn’t want to see them in the editor of course.

Luckily, after a bunch of code contributions and bug reports by Karelia, makers of SandVox, and then Mail.app using WebKit for editing styled e-mails, WebKit supports in-line editing. It is quite easy, actually: You just call [myWebView setEditable: YES] and give the WebView an empty HTML document. That is all you need to have a styled edit field from which you can get HTML and to which you can assign HTML.

Apple’s website also documents how to load HTML into the WebView, and how to get it back out. Loading is trivial using [[myWebView mainFrame] loadHTMLString: @"<html><body></body></html>"], and of course you can insert your HTML text in between these two tags. Writing them back out is slightly more complicated: What you do is get to the DOMDocument and then the documentElement from the mainFrame, then grab the element named @"body" out of that, and then you can typecast that to a DOMHTMLElement to obtain its innerHTML, which is a string containing the HTML for your styled text. If you want the full document and not just edit HTML fragments, you can simply take the document element’s outerHTML.

That was all straightforward so far, once I’d grown used to WebKit’s terminology. Now, how to manage the placeholders? Well, first, you will have to create a new WebKit plug-in project from the Standard Apple plug-ins category. This gives you a simple NSView, which you can associate with a MIME type by editing its Info.plist. Set up this project, so that it is built with your application project, and make sure you have a Copy Files build phase that copies it into a PlugIns folder in your application’s bundle.

You should now be able to specify an embed tag in your HTML source code with the type attribute set to your plugin’s MIME type, and WebKit will automatically load your plug-in and place it in this spot. However, you will either have to manually specify width and height attributes on the embed tag, or your plug-in will have to calculate the sizes, and use the arguments dictionary it gets passed on creation to add to them to the embed tag in code by manipulating the DOM tree through the DOMElement in WebPlugInContainingElementKey in the arguments dictionary. Since this key already refers to our embed tag, this is as simple as using the -setAttribute:value: call on this object, and using +stringWithFormat: to convert our sizes into strings.

What I learned from this? Once you know that there is no way to load a plug-in directly from inside your application, it is fairly straightforward to add your own objects to a WebView. Sadly, you always only know that after…

Cocoa Text System everywhere…

Sometimes, you need to draw text with more control than an NSTextField or NSTextView will let you do, and sometimes you need better performance than the NSStringDrawing category will provide. And maybe you need to draw text into a CGContext or even inside a Carbon application.

You may be thinking about CoreText right now, and how unfortunate it is that you still have to maintain compatibility with Mac OS X 10.4 “Tiger”, but there’s an easier way:

The Cocoa Text System

Just use the Cocoa Text System. The Cocoa Text System is a group of classes that NSTextView, NSTextField and NSStringDrawing use to actually draw strings. Now, if you look at Apple’s docs, you’ll first be frightened by how complex this whole system seems to be: there are NSLayoutManagers, NSTextStorages, NSTextContainers, NSGlyphGenerators, NSTypesetters… but don’t fear, it’s much easier than it looks.

Apple actually provides a great introduction in the Drawing Text with NSLayoutManager entry of the Drawing Strings Task Documentation.

If you read that, you’ll see that you actually only need to deal with three of these classes to draw any styled Unicode string wrapped to a text box: NSLayoutManager is kind of the main controller. The string to be drawn and its attributes are stored in an NSTextStorage, and the extents of the area to draw into is specified by the NSTextContainer. What’s more, once you’ve created these objects, you can cache them, and thus speed up repeated drawing of the same string significantly.

You create these objects using +alloc/-init as usual, then tell the layout manager to take ownership of the text container, and the text storage to take ownership of the layout manager. Here’s essentially Apple’s example:

NSTextStorage *textStorage = [[NSTextStorage alloc] initWithString:@"This is the text string."];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
NSTextContainer *textContainer = [[NSTextContainer alloc] init];
[layoutManager addTextContainer:textContainer];
[textContainer release];
[textStorage addLayoutManager:layoutManager];
[layoutManager release];

// Use the objects.

[textStorage release];

To actually draw this example string, you simply specify the size of the area to draw in, then ask the layout manager for the range of glyphs to draw, and then tell it to draw those at whatever position you want:

[textContainer setContainerSize: rect.size];
NSRange glyphRange = [layoutManager glyphRangeForTextContainer: textContainer];
[layoutManager drawGlyphsForGlyphRange: glyphRange atPoint: rect.origin];

Pretty simple, isn’t it? Two things to watch out for here: Whenever you change the size of the text container, the text needs to be re-wrapped (“re-layouted”), which is a sort of expensive operation that can be sped up by caching. Second, to actually trigger such a re-layout, you call -glyphRangeForTextContainer:.

For drawing styles and images, you simply take advantage of the fact that the NSTextStorage is actually a subclass of NSMutableAttributedString. So, it’s trivial to assign styles, fonts, colors and add text attachments.

Measuring Text

For example, if you want to measure how much space text will use, set the text container to have the height or width of the fixed side, and set the other side of the rect to some huge value, like FLT_MAX. Then, you call -glyphRangeForTextContainer: to make sure the text has been layouted, and then call -usedRectForTextContainer: to get the actual dimensions of the text:

[textContainer setContainerSize: NSMakeSize([self bounds].size.width, FLT_MAX)];
(NSRange) [layoutManager glyphRangeForTextContainer: textContainer]; // Cause re-layout.
NSRect neededBox = [layoutManager usedRectForTextContainer: textContainer];

The Cocoa Text System in Quartz or Carbon

Carbon uses the straight Quartz APIs. People who want to draw into OpenGL textures, PDF contexts and other custom locations often also use Quartz directly. So, what if you want to use the above text drawing methods in Quartz? You don’t have a an NSGraphicsContext, you only have a CGContext. What to do? Well, easy. Behind every NSGraphicsContext, there is a CGContext, and for every CGContext, you can create an NSGraphicsContext. So, if you have the CGContextRef in a variable named inContext, you can easily do:

[NSGraphicsContext saveGraphicsState];
NSGraphicsContext* context = [NSGraphicsContext graphicsContextWithGraphicsPort: inContext flipped: true];
[NSGraphicsContext setCurrentContext: context];

// Do Cocoa drawing here.

[NSGraphicsContext restoreGraphicsState];

Of course, if you’re doing this in Carbon, take care to catch any NSExceptions and create an autorelease pool around calls like these, you wouldn’t want to leak Cocoa objects or have a Cocoa exception waltz through the Carbon system libraries.

The neat part about this is not only that the Cocoa Text System is much simpler than ATSUI, but also that the Cocoa Text system is very similar in design to CoreText. So, if you want to move to CoreText a couple releases from now, you’ll just have to swap out a few API calls, but the general workings will stay pretty much the same.

How to become a games programmer on the Mac

From the “when you don’t have time to blog, drag out an old e-mail and post your side of it”-department:

[A simple computer game called Sterntaler]
 

How do I find beginners’ tutorials for Mac game programming?

In general, for Mac programming you’ll always find great resources on Scott Stevenson’s CocoaDevCentral and CocoaBlogs sites. There’s also the two Mac programming Wikis CocoaDev and CarbonDev.

For games programming, iDevGames is supposedly very popular. If you’re looking to do high-end, high-performance graphics work (i.e. not just the occasional animation), you’ll probably have to drop down to OpenGL, and for that the ultimate tutorial would be The NeHe OpenGL Tutorials, which also comes with info on how to do them on a Mac.

Would you recommend Cocoa or Carbon for games?

It depends. If you’re doing a lot of standard UI, Cocoa is definitely the better choice. If you’re doing a lot of custom UI, you won’t be using much of either UI library. Since Apple’s been frantically trying to saw off the branch on which Carbon sits in recent years, the decision has probably been made for you.

In the end, it again depends on your kind of game. If you’re doing a board game or another kind of game that only needs 2D graphics (and this includes pre-rendered 3D views, and thus also many isometric game graphics as long as they can’t be freely rotated), Cocoa’s NSViews will work.

Carbon has a leg up there with HIViews, because they are actually supported to be drawn overlapping. In Cocoa that works as of Leopard, though it’s a bunch more complicated. You may have to sort the view list occasionally, or switch on CoreAnimation layers (thus needlessly increasing system requirements to exclude lower-end graphics cards).

If your graphics are fairly simple (e.g. pre-rendered and similar size), you may also want to try using one huge view for all of them, and using the dirty rects (“update regions”) passed to you by the OS to selectively redraw only the parts that actually changed. This will give you less built-in behaviour, but will on the other hand forego some of the overhead all the built-in behaviour has.

Otherwise, you’ll probably be using OpenGL, which means you’ll probably just create a standard Cocoa app and stuff an NSOpenGLView in its main window, and that’ll be about all of Cocoa you’ll find yourself using. The remainder of the display code would probably be C OpenGL calls, maybe wrapped in C++ or Objective C classes for more manageability. If you’re wondering how you could use C++ in an NSOpenGLView, search the web for “Objective C++”, which is a way to use both ObjC and C++ in the same file.

What about sound?

For sound-output, Cocoa’s classes always were a bit rudimentary. Only as of Leopard, they finally allow volume control and specifying a device, making the sound loop and even specifying an output device and a channel mapping. Before that, the Carbon sound manager was close (though it was not quite easy to load sounds other than ‘snd ‘ (.sfil) and AIFF), but most people had to punt and just open an audio-only QuickTime movie and play that, either using NSMovie or later QTMovie. However, for most apps these APIs should be enough to play background music and the occasional sound effect.

If you need Tiger compatibility or anything more complicated, like real ambient sounds, you’ll probably find yourself dropping down to CoreAudio, which is a horribly complicated API for sound playback (For a taste: One CoreAudio engineer called pausing playback an “advanced feature” at a presentation). There’s an AUFilePlayer that can be made to work if your input is a file and you don’t need to know when it’s finished playing, but otherwise you’ll be in a bit of pain using that.

Alternately, you can leverage open source libraries whose Mac versions were built on top of CoreAudio, like OpenAL, to retain your sanity.

Any actual game programmers wanna chime in with their suggestions?

Funny thing about C parameter evaluation order…

I just explained this to a friend today, and thought this might make an interesting blog posting:

#include <stdio.h>

int main( int argc, const char * argv[] ) { char theText[2] = { 'A', 'B' }; char* myString = theText; printf( "%c, %c\n", *(++myString), *myString );

return 0; }

The above code is platform-dependent in C. Yes, you read correctly: platform dependent. And I’m not nitpicking that this may cause a problem if your compiler is old or that some compiler may not have printf() or the POSIX standard.

This code is platform-dependent, because the C standard says that there is no guarantee in which order the parameters of a function call get evaluated. So, if you run the above code, it could print B, B (which most of you probably expected because it corresponds to our left-to-right reading order) or it could print B, A.

If you want to test this and you own an Intel Mac, you can do the following thanks to Rosetta’s PowerPC emulation: Create a new “Standard Tool” project in Xcode and paste the above code into the main.c file. Switch to “Release” and change “Architectures” in the build settings for the release build configuration to be “ppc”. Build and Run. It’ll print B, B. Now change the architecture to “i386″ and build and run again. It’ll print B, A.

So, why doesn’t C define an order? Why did anyone think such odd behaviour was a good idea? Well, to explain that, we’ll have to look at what your computer does under the hood to execute a function call. In general, there are two steps: First, the parameters are evaluated and stored in some standardized place where the called function can find them, and then the processor “jumps” to the first command in the new function and starts executing it.

Some CPUs have registers inside the CPU, which are little variables that can hold short values, and which can be accessed a lot quicker than actually going over to a RAM chip and fetching a value. There are different registers for different kinds of values. Many CPUs have separate registers for floating-point numbers and integers. And just like with RAM, it’s sometimes faster to access these registers in a certain order.

So, it may be faster to first evaluate all integer-value parameters, and then those that contain floating-point values. Depending on what physical CPU your computer has (or in the case of Rosetta, what characteristics the emulated CPU your code is being run on has), these performance characteristics may be different. Some CPUs may have so few registers that the parameters will always have to be passed in RAM. Others may put larger parameters in RAM and smaller ones in registers, others again may put the first couple parameters in registers (maybe even distributing a longer parameter across several registers), and the rest that don’t fit in RAM, etc.

So, to make sure C can be made to run that little bit faster on any of these CPUs, its designers decided not to enforce an order for execution of parameters. And that’s one of the dangers of writing code in C++ or Objective C: It may look like a high-level language, but underneath it is still a portable assembler, with platform-dependencies like this.

Using other people's classes

I have a bunch of open source classes on Github, so occasionally some kind people send me bug fixes. I’m grateful for that, and it’s one of the reasons why I make the code available. Some people also add new features, which is also very cool.

However, in many cases, they add new features by changing my class. And that always makes that little object-orientation alarm clock in my head go off: One of the reasons why subclasses are available in OOP is to let people use and modify library code without having to copy and paste or touch the original. If you change the class someone else writes, and that person decides that this change, for whatever reason, won’t be merged into the main code base, you will have to use FileMerge each time a new version is released, to apply your changes to the new version.

However, if you write a subclass that adds the features, you just drop in the updated base class, and the magic of inheritance will take care of doing the “merge” for you.

Mind you, I’m not complaining here. I’ve received some great submissions for some of my classes, from people like Todd Ransom, David Sinclair, David Rozga, and many others I’ve probably forgotten. Not to mention that, after I’ve stared at the same code for weeks, I just don’t see that missing [super dealloc] call anymore, and I’m grateful for the people who e-mail me and tell me. But I sometimes have plans for a certain class, and some changes some people suggest would collide with those. Or a certain change would break my or other users’ applications because it changes the behaviour of the class, and I have to turn it down.

If you write a subclass or a category that applies your changes, not only is your code completely self-contained and you don’t have to merge text files, it also makes it very easy for me to look at the code and see only your changes, without having to fire up diff myself, which may not be possible in an internet cafe anyway. And if I want to integrate it into the “official” version, I can easily copy and paste the stuff over. I’ll have to merge anyway, because I may also have made changes in the meantime.

Now, I won’t turn down a feature because it didn’t come as a subclass. I’m just saying that you could have a Shiny Happy Object-Oriented Feeling(tm), make it easy on yourself to get future updates until I get around to adding your modifications, and make it easier for me to check out your changes on the road.

Generating Machine Code at Runtime

Okay, so my next attempt at learning how my computer works and how to speak machine language is the following C code fragment:

typedef int (*FuncPtr)();

// Create a function:
char            testFunc[] = { 0x90,                         // NOP (not really necessary...)
                               0xB8, 0x10, 0x00, 0x00, 0x00, // MOVL $16,%eax
                               0xC3 };                       // RET

// Make a copy on the heap, OS doesn't like executing the stack:
FuncPtr         testFuncPtr = (FuncPtr) malloc(7);
memmove( (void*) testFuncPtr, testFunc, 7 );

printf("Before function.\n");
int result = (*testFuncPtr)();
printf("Result %d\n", result);

Basically, this stores the raw opcodes of a function in an array of chars. The first byte of each line is usually the opcode, i.e. 0x90 is No-Op, 0xB8 is a MOVL into the eax register (with the next 4 bytes being the number to store, in this case 16), and 0xC3 is the return instruction (I had to look up the opcodes in Intel’s documentation).

One thing to watch out for here (at least on Mac OS X), is that you’ll get a bad access error if you try to execute testFunc directly. That’s because testFunc is on the stack, and the stack shouldn’t contain executable code (it’s a small safety measure). So, what we do is we simply malloc some memory on the heap, and stuff our code in there.

You may wonder why I’m using eax of all registers to store my number 16 in. Easy: Because the convention is that an int return value (and most other 4-byte return values) goes in eax when a function returns. So, what this does is it essentially returns 16. Which our printf() proves. Neat!

Intel’s documentation describes the opcodes in a very complicated way, so what I essentially do is I write some assembler code and enclose the instruction whose byte sequence I want to find out in instructions whose byte sequence I already know (I like to use six nops, which are short and show up as 0x90 90 90 90 90 90). Then I compile that, and then use a hex editor to search for the known instructions, and whatever is between them must be my new one. Here’s a small table of other operations you may find in the typical program and what byte sequences they turn to:

0×50 pushl %eax
0×53 pushl %ebx
0×55 pushl %ebp
0×89 E5 movl %esp, %ebp
0×90 nop
0xB8 NN NN NN NN movl $N, %eax
0×68 NN NN NN NN pushl $N
0xE8 NN NN NN NN call relativeOffsetNFromEndOfInstruction
0x8B 1C 24 movl (%esp), %ebx
0x8D 83 NN NN NN NN leal relativeOffsetToData(%ebx), %eax
0x8D 85 NN NN NN NN leal relativeOffsetToData(%ebp), %eax
0x5B popl %ebx
0×83 C4 NN addl $NN,%esp
0×83 EC NN subl $NN,%esp
0x8B 00 movl (%eax), %eax
0×89 45 NN movl %eax, NN(%ebp)
0xC9 leave
0xC3 ret

The code fragment above is essentially what one would need to create a just-in-time compiler. For a real compiler, instead of executing this directly, we’d have to write it to a complete MachO file and link it with crt1.o.

Update: on top of the instructions for position-independent code (PIC), I’ve also added some more useful in passing structs as parameters on the stack.

Intel assembler on Mac OS X

I’ve always wanted to learn another assembler, and with one of my colleagues being a real assembler guru, and the Intel reference books on my bookshelf, and the Intel switch just behind us, I thought this would be a good opportunity to finally get going with x86 assembler.

Now, assembler programming under Mac OS X isn’t quite as well documented as one would wish. There’s no tutorial that I could find (lots of tutorials for Linux and Windows, but none for Mac OS X yet). This won’t be one either, but rather this is a blog posting of me sharing what I found out about assembler on OS X, and is probably only useful to someone who already knows some assembler, but just doesn’t know Intel on Mac OS X. My main approach is to compile C source code into assembler source files using GCC. Then I can look at that code and find out what assembler instructions correspond to what C command. If all of this turns out to be correct and I should happen to have loads of time on my hand, I may still go out there and turn this into a decent tutorial.

The basics are pretty simple

	.text						# start of code indicator.
.globl _main					# make the main function visible to the outside.
_main:							# actually label this spot as the start of our main function.
	pushl	%ebp				# save the base pointer to the stack.
	movl	%esp, %ebp			# put the previous stack pointer into the base pointer.
	subl	$8, %esp			# Balance the stack onto a 16-byte boundary.
	movl	$0, %eax			# Stuff 0 into EAX, which is where result values go.
	leave						# leave cleans up base and stack pointers again.
	ret							# returns to whoever called us.

Now, the underscore in front of “main” is a convention in C, so just accept it. When you enter the _main function, the return address (i.e. the instruction where the program will continue after the function has finished, aka “back pointer”) has already been pushed on the stack, taking up 4 bytes. We also save the base pointer (the point where our caller can find its parameters on the stack) to the stack, and set it to the current stack pointer (which is where our parameters are). That takes another 4 bytes, so we have 8 bytes now. Since the stack should be aligned on 16 bytes before you can make a call to another function, we subtract another 8 from the stack pointer, which pads out the stack (we could also just do two “pushl $0″ for the same effect). If we used any local variables, we would use this opportunity to subtract more for them.

Now comes the actual body of our function. What we do is simply return 0. This is done by stuffing 0 in the eax register.

Finally, we have the tail end of our function, which calls leave (which cleans up by restoring our caller’s base pointer and stack pointer) and then call ret, which pops the return address off the stack and continues execution there.

Calling a local function

Calling a function is fairly simple, as long as it’s a local one right in the same file as ours. In that case, what you do is you first declare that function:

	.text
.globl _doSomething				# Our doSomething function.
_doSomething:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	nop							# does nothing.
	leave
	ret
.globl _main
_main:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$24, %esp			# 8 to align, 16 for our 4-byte parameter and padding.
	movl	$3, (%esp)			# write our parameter at the end of the stack (i.e. padding goes first).
	call	_doSomething		# call doSomething.
	movl	$0, %eax
	leave
	ret

“nop” is a do-nothing instruction I just inserted here to show where doSomething’s code would go. That’s pretty easy. You just write the function, push the parameters on the stack and use call to jump to the function, and that will take care of pushing the return address and all that. The only tricky thing is passing the parameters. You have to pad first, and then push (or mov, in our case) the parameters in reverse order (i.e. #1 is at the bottom of the stack, #2 above it etc.). That’s because otherwise the function being called would have to skip the padding. Well, could be worse.

Accessing parameters

To acess any parameters, you address relative to the base pointer. The value immediately at the base pointer is generally your caller’s base pointer and the return address, so you need to add 4 + 4 = 8 bytes. Yes, since the stack starts at the end of memory and grows towards the beginning, and you subtract from the stack pointer to make it larger, you need to add to the stack pointer to find something on the stack. The same applies to our base pointer, of course:

	movl	12(%ebp), %eax	# get parameter 2 at offset 4 + 4 + 4
	addl	8(%ebp), %eax	# get parameter 1 at offset 4 + 4

Would store your second parameter in eax and then add the first parameter to it, leaving the result in eax, where it’s ready for use as a return value. Note the ##(foo) syntax, which adds the number ## to the pointer foo. This is register-relative addressing.

An added benefit of this is that you can actually pass more parameters to a function than it knows to handle, and it will just ignore the rest.

Fetching data

To access data (e.g. strings), it gets trickier. You declare data like the following:

	.cstring
myHelloWorld:
	.ascii "Hello World!\0"
	.text
.globl _main
_main:
. . .

So, you add a .cstring section at the top of the function, and in that you declare a label and use the .ascii keyword to actually stash your string there. So far, so good, there’s only one problem:

All data manipulation is done using absolute addresses. But we don’t know at what position in memory our program will be loaded. Labels aren’t absolute addresses, they get compiled into relative offsets from the start of our code. So, how do we find out at which absolute address our string myHelloWorld is? Well, the trick MachO uses is that it knows that our program will be loaded as one huge chunk. So, we know that the distance between any of our instructions in the code will always stay at the same distance to our string.

So, if we could only get the address of one instruction in our code that has a label, we could calculate the absolute address of our string from that. Now, look above, at our function call code. Notice anything? Our return address is an absolute pointer to the next instruction after a function call. So, all we need to do to get our address is call a function. When you assemble C source code, they call this helper function ___i686.get_pc_thunk.bx, which is quite a mouthful. Let’s just call it _nextInstructionAddress:

. . .
	call	_nextInstructionAddress
myAnchorPoint:
. . .

That’s what we call somewhere at the start of our code to find our own address. Note how I cleverly already added a label myAnchorPoint, which labels the instruction whose address we’ll get. Then we somewhere (e.g. at the bottom) define that function:

. . .
_nextInstructionAddress:
	movl	(%esp), %ebx
	ret

We don’t even bother aligning the stack or changing and restoring the base pointer. This simply peeks at the last item on the stack (the return address) and stashes that in register ebx. Then it returns (and obviously doesn’t call leave because we pushed no base pointer that it could restore).

Once we have this address in ebx, we can do the following to get our string’s address into a register, and from there onto the stack:

. . .
	leal	myHelloWorld-myAnchorPoint(%ebx), %eax
	movl	%eax, (%esp)
. . .

LEA means “Load Effective Address”, i.e. take an address and stash it into a register. myHelloWorld-myAnchorPoint calculates the difference between our two labels, and thus tells us how far myHelloWorld is from myAnchorPoint. Since myHelloWorld is probably at the start of the program, e.g. at address 3 maybe, and myAnchorPoint further down, say at address 20, what we get is a negative value, e.g. -17. And xxx(%ebx) is how you tell the assembler that you want to add an offset to a register to get a memory address. ebx contains the address of myAnchorPoint, so what this does is subtract 17 from myAnchorPoint’s absolute address, giving us the absolute address of myHelloWorld! Whooo! And this mess is called “position-independent code”.

Now, our call to LEAL loads a “Long” (which is 32 bits, i.e. the size of a pointer on a 32-bit CPU) and stashes it into register eax. And the movl call moves that long from our register into the last item on the stack, ready for use as a parameter to a function.

Calling a system function

Now, it’d be really nice if we could printf() or something, right? Well, trouble is, we don’t know the address of printf(). But this time it’s actually easy. We add a new section at the bottom of our code:

. . .
	.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
_printf_stub:
	.indirect_symbol _printf
	hlt ; hlt ; hlt ; hlt ; hlt
_getchar_stub:
	.indirect_symbol _getchar
	hlt ; hlt ; hlt ; hlt ; hlt

This is a new section named __IMPORT,__jump_table. It has the type symbols_stubs and the attributes self_modifying_code and pure_instructions. 5 is the size of the stub, and intentionally is the same as the number of hlt statements below.

This section is special, because when our code is loaded, the loader will look at it. It will see that there is an .indirect_symbol directive for a function named “printf”, and will look up that function. Then it will replace the five hlt instructions, each of which is one byte in size, with an instruction to jump to that address (hence the self_modifying_code). We also added a label for each indirect symbol, which we name the same as the symbol, just with “_stub” appended.

So, to call printf, all you have to do now is push the string on the stack and then

	call	_printf_stub

Which will jump to _printf_stub and immediately continue to printf itself. And just to show you that you can have several such imported symbols, I’ve also included a stub for getchar. Now note that the system usually doesn’t name these symbols “_foo_stub”, but rather “L_foo$stub” (yes, a label name can contain dollar signs. You can even put the label in quotes and have spaces in it…). Same difference.

Okay, so that’s how much I’ve guessed my way through it so far. Comments? Corrections? If you want

PS – Thanks to John Kohr, Alexandre Colucci, Jonas Maebe, Eric Albert and Jordan Krushen, all of which helped me figure this out one way or the other. Thanks, guys!

Update: Added mention of how to actually access parameters.