c

3 entries have been tagged with c.

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.

Debugging memory on OS X

Just a short note so I don’t have to Google around Apple’s web site for hours: There’s a few useful environment variables that can be set to help in debugging disposed memory accesses etc. Most of them are documented on Enabling the mallocDebug features and Finding memory leaks:

  • Set DYLD_INSERT_LIBRARIES to /usr/lib/libMallocDebug.A.dylib. This makes you link against libMallocDebug, which prints errors on bad accesses. Set a breakpoint on MDprintf to see a backtrace when this triggers.
  • set MallocScribble and MallocPreScribble to YES to initialize new memory to 0xAA and freed memory to 0×55, which will also help finding out when you’re accessing bad memory.
  • set MallocGuardEdges to YES to make it harder to smash memory and instead get a bad access exception.

Any other memory debug tricks you guys have?

I am not recycling – I collect garbage!

The last couple weeks were very busy at work. We had to get the new site into a state where it could be presented to a representative of the customer’s. So, when I returned, I was pretty exhausted and usually spent my time catching up on sleep. What little time I had left, however, I spent on a little endeavour that I’d wanted to try for a long while. For this SEKR1T PR0JEKT, I needed a programming language. After a little search, I came across Lua, which is a very lightweight, very flexible and powerful embeddable scripting language. It’s under a very liberal MIT-style license, and sticks mostly to ANSI C and thus compiles beautifully out of the box.

I absolutely adored its object model. You have numbers and strings, and then you have tables – essentially associative arrays or maps. For any table you can define a meta-table that can serve as its super-class, providing values for keys that aren’t present in your subclass, and since functions are just another kind of data type in Lua, you can simply assign a function to a table entry and then call it using good old dot-syntax and brackets. Essentially, it’s the same kind of prototype-based programming that I liked about TADS, and which is also used by other languages like Io and Self.

Another advantage of Lua is that it was built to integrate easily with a host application. You can create custom userdata objects that wrap around a C data structure or pointer to a C++ object, and you get notified when your object is garbage collected or someone calls one of its methods. You can also register C functions with Lua so your scripts can call it.

The downside of Lua is that it is very general-purpose. The features were chosen in a way that lets you do everything, but some of them are a little complicated to do, and others use two very similar syntax notations where simply holding down the shift key too long gives you very similar behaviour but not the same. On top of that, Lua’s developers don’t give any guarantees regarding backwards compatibility. The byte code and the API may change without further notice, and byte code compiled by an older version of Lua can’t be run in a newer one. So, while Lua worked pretty nicely for my test app, it turned out not to be a viable option after all. The parser was also pretty odd code that I really didn’t manage to read very well, so my plans to fork the code-base and fix some of the syntax issues were pretty quickly laid to rest.

So, what do you do when you find n cool tools but none that has everything you need? You write the n +1th one yourself. I’m not sure whether I’ll ever finish this, but today I did the basic object model. Ints, Strings, Tables, and a garbage collector to go with them. Due to prolonged exposure to Cocoa, I had already done several reference counting implementations, but this time I decided I wanted something that just worked, without having to worry about circular references. So I read a little about mark-and-sweep garbage collectors, which seemed simple enough.

Essentially, a mark-and-sweep garbage collector assumes that there is one central hierarchy in which all objects are. Usually, this hierarchy is rooted in the list of global variables. In addition, the garbage collector has a list of all existing objects (or knows how to find them). Every object has an associated “reachable” flag. When the garbage collector runs, it first sets all objects’ “reachable” flags to FALSE. Then it does a deep search through the object hierarchy and marks all objects it comes across as reachable. If you have any orphaned chains of circular-retained objects, where each one holds on to the other, those aren’t part of the tree anymore and stay marked as unreachable. All you have to do is sweep over your list of objects and de-allocate each one marked as unreachable.

Simple and beautiful, except if you have a lot of objects, in which case running the garbage collector takes a bunch of time, which is where garbage collectors got their bad reputation from. Of course, there are ways to optimise this. For instance, you can use reference counting as your primary garbage-collection method and then run the collector a lot less often to get rid of the occasional retain-circle.

Another approach which is more complex is having an incremental garbage collector. I.e. instead of marking and sweeping all objects at once, you only process part of the list. Of course, this opens a whole other can of worms if an object moves from a not yet processed object to one that has already been processed. It will then never be marked as reachable. You could of course just have one object inherit its owner’s “reachable” flag if the container is marked as reachable, and thus at least avoid deallocating an object too early, but there may be other holes to be avoided.

Anyway: Next stop is actually writing the programming language around that, and drinking a cup of that delicious “Kiba Flip” tea that just finished (pineapple, banana, cherry … mhhh…). And yeah, it’s real tea, not that bagged stuff I’ve been drinking the last weeks :-)