Blog

Anonymous Functions in C/C++?

I was reading my fair share of feeds for the day and I found some links for a nice site that translates C gibberish to English like this: int (*(*foo)(void ))[3] gets translated to “declare foo as pointer to function (void) returning pointer to array 3 of int” – pretty cool on itself but what really caught my attention was another of the samples: int (^*(^foo)(void (^*)(int (^)(int *))))(void )

I’ve seen many languages and been doing this for quite some time but I’ve never seen that syntax anywhere, what the hell is that ^ and ^* in C/ObjC/C++? And checking the mentioned site’s “translation” I got a small bread crumb to follow, it’s called a Block, but what is it?

It turns out that after a few search queries I found that its an Apple’s extension to their GCC/LLVM implementations, they have a lot of those but the truly amazing is what blocks turn out to be – Anonymous Functions! In C# you’ve delegates and somehow similar you’ve function pointers in the C world, however in C# anonymous method you’ve closure and type inference which are missing in C. Blocks enable that. There’s nothing like code to help getting up to speed:

Inline anonymous function

my_block = ^(void) { printf("hello world\n"); };

That’s the basic syntax, very similar to C#. Since you’ve type inference and no args are needed in this case one could even omit the (void) from the expression.

Hello Closures

typedef void (^blockWithString)(char*);
char *greeting = “hello”;
blockWithString b = ^(char* place){ printf("%s %s\n", greeting, place); };
greeting = “goodbye”;
b(“closures”); // prints “hello closures\n”

Blocks capture read-only copies of local variables. You can however get read/writable access by using global or static variables as well as declaring them with the  __block storage type.

__Block “scope”

#include stdio.h
#include Block.h
typedef int (^IntBlock)();

IntBlock MakeCounter(int start, int increment) {
	__block int i = start;

	return Block_copy( ^ {
		int ret = i;
		i += increment;
		return ret;
	});

}

int main(void) {
	IntBlock mycounter = MakeCounter(5, 2);
	printf("First call: %d\n", mycounter());
	printf("Second call: %d\n", mycounter());
	printf("Third call: %d\n", mycounter());

	/* because it was copied, it must also be released */
	Block_release(mycounter);

	return 0;
}
/* Output:
	First call: 5
	Second call: 7
	Third call: 9
*/

This was taken from Wikipedia and demonstrates how one can capture mutable states in the surrounding scope to create an integer range iterator.

The possibilities are endless but I find it of particular interest for GNOME or iPhone development, being able to use this would make lower-level multi-threading and async programming much easier. Since I do quite a bit of iPhone development myself I think its time to start researching if this is available to me today or if I need to wait. Two good resources I’ve found on the subject are the Wikipedia and the Apple pages.

Meanwhile, let me suggest any GCC or GNOME developer that might be reading that this is a huge thing to consider porting upstream and make it available for everyone! I promise my 2 chocolate bars to the first to commit 😛 Can you resist the candy?

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Reddit Post to StumbleUpon

Tags: , , , ,

3 Responses to “Anonymous Functions in C/C++?”

  1. Bergamot says:

    I’ve been using Plausible Blocks on the iPhone for a few months, and everything seems to work great:

    http://code.google.com/p/plblocks/

    It’s a backport of Apple’s block additions to the versions of GCC that they include with 10.5/10.6. You just install it, add the runtime framework to your Xcode project, choose the PLBlocks compiler, and suddenly you have closures working on the iPhone.

    The only feature that I miss is that you give up the Static Analysis notes you’d get from the new Clang compiler.

  2. Ruby, which main features are blocks and closures, have similar syntax, but a lot more clearer, and since I never heard about these C features, this will be somewhat easy to use (assuming the Ruby background).

Leave a Reply

For spam filtering purposes, please copy the number 7659 to the field below: