Blocks vs. C++ lambda's?


I learned about the blocks feature Apple is implementing as an extension to C. After looking at it briefly, I concluded it’s basically the same thing as C++(0x) lambdas. But there should be a difference since if not, (I guess) it would make sense to just adopt the C++ lambda syntax in C and Obj-C to achieve the goal. So could someone please point out what blocks provide that C++ lambdas do not (and vice versa)?

Boris Dušek


The non-serious answer would be: because the C++(0x) syntax sucks. :stuck_out_tongue:

And now the serious answer: from what I can tell, C++(0x) lambdas cannot be used outside of their declaration scope at least if it uses variables that are contained in the innermost block scope of its creation...

Whereas Apple's blocks have a few advantages, first they have a simple syntax, their type declaration is very close from function pointers (you replace * by ^), second, you don't need to declare which variables from the enclosing scope you want to use inside your block...
All of them can be used inside, in case you want to modify one of the captured variables, you need to add the __block type specifier in front of the variable declarations. This is the equivalent to the [&total]{ total += 5; } syntax that is used in C++'s lambdas, the reference & operator doesn't mean the same thing in C, and we need the blocks to be compatible with C.

And most importantly, the best reason to prefer Apple's feature is that you can fully use the blocks outside of their declaration scope, even though the variables (__block or not) from the enclosing scope are no more on the current stack frame. This is done by copying the block to the heap along with all the variables it uses, and if two blocks uses/modifies the same __block variable in the declaration scope, both blocks will see the same changes, even when copied on the heap.

Other reasons to prefer Apple's feature is that it's fully available in C, C++ and ObjC altogether, it supports the garbage collection of ObjC with __weak __block variables, it has additions for ObjC and C++ types, and also, it's a first class object in ObjC and can thus receive messages.

Remy Demarest

Remy, Boris,

This is a really interesting discussion to have, but I don't believe it belongs on this mailing list because it will not be seen by people familiar with C++ lambdas. I suggest bringing your question to comp.lang.c++.moderated.

  - Doug

C++ supports [=]{...} syntax which takes copies and lets you use
variables after the originals have gone out of scope. Is that what
you're looking for?

An other (minor) pro for Apple's block is that 'return type inference' works even if their is more than one statement in the block.

Doug and others,

I submitted it to comp.lang.c++.moderated, will post the link when the thread is available there.
Thanks, Boris

I submitted it to comp.lang.c++.moderated, will post the link when the thread is available there.


Well, yes and no...

For starter, Apple's syntax doesn't need you to say anything about capturing variables, they're just captured. The [=]{} seems to be equivalent with normal variables, their value is copied inside the block's structure and it's constant.

But I was talking about __block variables. You add "__block" in front of a variable declaration and then you're allowed to modify its value inside the block, and that change is mirrored in every blocks in the same scope that capture that variable, too.

Remy Demarest