[cfe-dev] "Blocks" in Clang (aka closures)

Bill Bumgarner bbum at apple.com
Tue Sep 2 09:01:18 PDT 2008


On Sep 2, 2008, at 8:27 AM, David Chisnall wrote:
> 1) In Seaside (Smalltalk web-app framework) blocks are used as a way
> of implementing continuation passing.  This requires support for re-
> binding variables in the closure.  Smalltalk does this via the
> BlockContext object.  Is there an equivalent of it here?

I'm not familiar with Seaside, so generically...

All local variables are const-copied into the block (if used, of  
course -- if not, nothing happens) unless marked with __block.

int x = 3;
__block int y = 4;

^{
    // effectively 'const int x;' here
    x = 4; // error
    y = 5; // works fine
};

Global variables work just like they do everywhere else.

... more below ...

> 2) I know of two existing implementations of blocks in Objective-C,
> one by Brad Cox in 1991 and one by David Stes in 1998.  Both used
> similar syntax (David Stes simply made untyped arguments default to
> id).  What was the rationale for designing a new syntax for block
> literals?  Was this to allow Objective-C syntax blocks which are
> objects encapsulating C blocks?

The goal is to realize a syntax and feature that is:

- compatible with C, C++, and Objective-C
- a relatively familiar syntax
- fast (hence, Blocks start out as stack based)
- complete

> 3) Why is the __block storage class required as an explicit type
> tag?  Can this not be inferred by the compiler (i.e. any variable you
> assign to in the block is promoted, others are copied)?

We initially pursued such a syntax and then abandoned it.

Specifically, a variable used by-reference is different;   it is  
accessed via a level of indirection and applying & to grab the address  
can produce surprising results.   Automatic promotion would be  
surprising and a move away from the precision of C.

Like auto, register, and static, __block is a different class of  
storage.

> 3a) It isn't clear from your example what happens if I create a block
> referencing a (non-__block) variable, assign it to a global variable
> (or an instance variable in another object somewhere), modify the
> referenced variable on the stack, and then invoke the block
> function.  Does the block see the old or the new value?  If it's the
> old value, then I think this answers my previous question but sounds
> like it will confuse programmers.  It seems that it would be less
> confusing if every block-reference variable implicitly received the
> __block storage class, and an explicit tag was made available for
> variables which should be bound-by-copy.

The value of non-block variables are bound at the time execution  
passes over the block declaration.

That is:

int x = 5;

int (^bX)() = ^{ return x; }

x = 6;

bX(); // returns 5

The argument could be made either way about default behavior.  In the  
end, we decided on a default behavior that impacts variable use and  
behavior *outside* of the block as little as possible.

b.bum




More information about the cfe-dev mailing list