reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
  208
  209
  210
  211
  212
  213
  214
  215
  216
  217
  218
  219
  220
  221
  222
  223
  224
  225
  226
  227
  228
  229
  230
  231
  232
  233
  234
  235
  236
  237
  238
  239
  240
  241
  242
  243
  244
  245
  246
  247
  248
  249
  250
  251
  252
  253
  254
  255
  256
  257
  258
  259
  260
  261
  262
  263
  264
  265
  266
  267
  268
  269
  270
  271
  272
  273
  274
  275
  276
  277
  278
  279
  280
  281
  282
  283
  284
  285
  286
  287
  288
  289
  290
  291
  292
  293
  294
  295
  296
  297
  298
  299
  300
  301
  302
  303
  304
  305
  306
  307
  308
  309
  310
  311
  312
  313
  314
  315
  316
  317
  318
  319
  320
  321
  322
  323
  324
  325
  326
  327
  328
  329
  330
  331
  332
  333
  334
  335
  336
  337
  338
  339
  340
  341
  342
  343
  344
  345
  346
  347
  348
  349
  350
  351
  352
  353
  354
  355
  356
  357
  358
  359
  360
  361
.. role:: block-term

=================================
Language Specification for Blocks
=================================

.. contents::
   :local:

Revisions
=========

- 2008/2/25 --- created
- 2008/7/28 --- revised, ``__block`` syntax
- 2008/8/13 --- revised, Block globals
- 2008/8/21 --- revised, C++ elaboration
- 2008/11/1 --- revised, ``__weak`` support
- 2009/1/12 --- revised, explicit return types
- 2009/2/10 --- revised, ``__block`` objects need retain

Overview
========

A new derived type is introduced to C and, by extension, Objective-C,
C++, and Objective-C++

The Block Type
==============

Like function types, the :block-term:`Block type` is a pair consisting
of a result value type and a list of parameter types very similar to a
function type. Blocks are intended to be used much like functions with
the key distinction being that in addition to executable code they
also contain various variable bindings to automatic (stack) or managed
(heap) memory.

The abstract declarator,

.. code-block:: c

   int (^)(char, float)

describes a reference to a Block that, when invoked, takes two
parameters, the first of type char and the second of type float, and
returns a value of type int.  The Block referenced is of opaque data
that may reside in automatic (stack) memory, global memory, or heap
memory.

Block Variable Declarations
===========================

A :block-term:`variable with Block type` is declared using function
pointer style notation substituting ``^`` for ``*``. The following are
valid Block variable declarations:

.. code-block:: c

    void (^blockReturningVoidWithVoidArgument)(void);
    int (^blockReturningIntWithIntAndCharArguments)(int, char);
    void (^arrayOfTenBlocksReturningVoidWithIntArgument[10])(int);

Variadic ``...`` arguments are supported. [variadic.c] A Block that
takes no arguments must specify void in the argument list [voidarg.c].
An empty parameter list does not represent, as K&R provide, an
unspecified argument list.  Note: both gcc and clang support K&R style
as a convenience.

A Block reference may be cast to a pointer of arbitrary type and vice
versa. [cast.c] A Block reference may not be dereferenced via the
pointer dereference operator ``*``, and thus a Block's size may not be
computed at compile time. [sizeof.c]

Block Literal Expressions
=========================

A :block-term:`Block literal expression` produces a reference to a
Block. It is introduced by the use of the ``^`` token as a unary
operator.

.. code-block:: c

    Block_literal_expression ::=   ^ block_decl compound_statement_body
    block_decl ::=
    block_decl ::= parameter_list
    block_decl ::= type_expression

where type expression is extended to allow ``^`` as a Block reference
(pointer) where ``*`` is allowed as a function reference (pointer).

The following Block literal:

.. code-block:: c

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

produces a reference to a Block with no arguments with no return value.

The return type is optional and is inferred from the return
statements. If the return statements return a value, they all must
return a value of the same type. If there is no value returned the
inferred type of the Block is void; otherwise it is the type of the
return statement value.

If the return type is omitted and the argument list is ``( void )``,
the ``( void )`` argument list may also be omitted.

So:

.. code-block:: c

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

and:

.. code-block:: c

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

are exactly equivalent constructs for the same expression.

The type_expression extends C expression parsing to accommodate Block
reference declarations as it accommodates function pointer
declarations.

Given:

.. code-block:: c

    typedef int (*pointerToFunctionThatReturnsIntWithCharArg)(char);
    pointerToFunctionThatReturnsIntWithCharArg functionPointer;
    ^ pointerToFunctionThatReturnsIntWithCharArg (float x) { return functionPointer; }

and:

.. code-block:: c

    ^ int ((*)(float x))(char) { return functionPointer; }

are equivalent expressions, as is:

.. code-block:: c

    ^(float x) { return functionPointer; }

[returnfunctionptr.c]

The compound statement body establishes a new lexical scope within
that of its parent. Variables used within the scope of the compound
statement are bound to the Block in the normal manner with the
exception of those in automatic (stack) storage. Thus one may access
functions and global variables as one would expect, as well as static
local variables. [testme]

Local automatic (stack) variables referenced within the compound
statement of a Block are imported and captured by the Block as const
copies. The capture (binding) is performed at the time of the Block
literal expression evaluation.

The compiler is not required to capture a variable if it can prove
that no references to the variable will actually be evaluated.
Programmers can force a variable to be captured by referencing it in a
statement at the beginning of the Block, like so:

.. code-block:: c

  (void) foo;

This matters when capturing the variable has side-effects, as it can
in Objective-C or C++.

The lifetime of variables declared in a Block is that of a function;
each activation frame contains a new copy of variables declared within
the local scope of the Block. Such variable declarations should be
allowed anywhere [testme] rather than only when C99 parsing is
requested, including for statements. [testme]

Block literal expressions may occur within Block literal expressions
(nest) and all variables captured by any nested blocks are implicitly
also captured in the scopes of their enclosing Blocks.

A Block literal expression may be used as the initialization value for
Block variables at global or local static scope.

The Invoke Operator
===================

Blocks are :block-term:`invoked` using function call syntax with a
list of expression parameters of types corresponding to the
declaration and returning a result type also according to the
declaration. Given:

.. code-block:: c

    int (^x)(char);
    void (^z)(void);
    int (^(*y))(char) = &x;

the following are all legal Block invocations:

.. code-block:: c

    x('a');
    (*y)('a');
    (true ? x : *y)('a')

The Copy and Release Operations
===============================

The compiler and runtime provide :block-term:`copy` and
:block-term:`release` operations for Block references that create and,
in matched use, release allocated storage for referenced Blocks.

The copy operation ``Block_copy()`` is styled as a function that takes
an arbitrary Block reference and returns a Block reference of the same
type. The release operation, ``Block_release()``, is styled as a
function that takes an arbitrary Block reference and, if dynamically
matched to a Block copy operation, allows recovery of the referenced
allocated memory.


The ``__block`` Storage Qualifier
=================================

In addition to the new Block type we also introduce a new storage
qualifier, :block-term:`__block`, for local variables. [testme: a
__block declaration within a block literal] The ``__block`` storage
qualifier is mutually exclusive to the existing local storage
qualifiers auto, register, and static. [testme] Variables qualified by
``__block`` act as if they were in allocated storage and this storage
is automatically recovered after last use of said variable.  An
implementation may choose an optimization where the storage is
initially automatic and only "moved" to allocated (heap) storage upon
a Block_copy of a referencing Block.  Such variables may be mutated as
normal variables are.

In the case where a ``__block`` variable is a Block one must assume
that the ``__block`` variable resides in allocated storage and as such
is assumed to reference a Block that is also in allocated storage
(that it is the result of a ``Block_copy`` operation).  Despite this
there is no provision to do a ``Block_copy`` or a ``Block_release`` if
an implementation provides initial automatic storage for Blocks.  This
is due to the inherent race condition of potentially several threads
trying to update the shared variable and the need for synchronization
around disposing of older values and copying new ones.  Such
synchronization is beyond the scope of this language specification.


Control Flow
============

The compound statement of a Block is treated much like a function body
with respect to control flow in that goto, break, and continue do not
escape the Block.  Exceptions are treated *normally* in that when
thrown they pop stack frames until a catch clause is found.


Objective-C Extensions
======================

Objective-C extends the definition of a Block reference type to be
that also of id.  A variable or expression of Block type may be
messaged or used as a parameter wherever an id may be. The converse is
also true. Block references may thus appear as properties and are
subject to the assign, retain, and copy attribute logic that is
reserved for objects.

All Blocks are constructed to be Objective-C objects regardless of
whether the Objective-C runtime is operational in the program or
not. Blocks using automatic (stack) memory are objects and may be
messaged, although they may not be assigned into ``__weak`` locations
if garbage collection is enabled.

Within a Block literal expression within a method definition
references to instance variables are also imported into the lexical
scope of the compound statement. These variables are implicitly
qualified as references from self, and so self is imported as a const
copy. The net effect is that instance variables can be mutated.

The :block-term:`Block_copy` operator retains all objects held in
variables of automatic storage referenced within the Block expression
(or form strong references if running under garbage collection).
Object variables of ``__block`` storage type are assumed to hold
normal pointers with no provision for retain and release messages.

Foundation defines (and supplies) ``-copy`` and ``-release`` methods for
Blocks.

In the Objective-C and Objective-C++ languages, we allow the
``__weak`` specifier for ``__block`` variables of object type.  If
garbage collection is not enabled, this qualifier causes these
variables to be kept without retain messages being sent. This
knowingly leads to dangling pointers if the Block (or a copy) outlives
the lifetime of this object.

In garbage collected environments, the ``__weak`` variable is set to
nil when the object it references is collected, as long as the
``__block`` variable resides in the heap (either by default or via
``Block_copy()``).  The initial Apple implementation does in fact
start ``__block`` variables on the stack and migrate them to the heap
only as a result of a ``Block_copy()`` operation.

It is a runtime error to attempt to assign a reference to a
stack-based Block into any storage marked ``__weak``, including
``__weak`` ``__block`` variables.


C++ Extensions
==============

Block literal expressions within functions are extended to allow const
use of C++ objects, pointers, or references held in automatic storage.

As usual, within the block, references to captured variables become
const-qualified, as if they were references to members of a const
object.  Note that this does not change the type of a variable of
reference type.

For example, given a class Foo:

.. code-block:: c

      Foo foo;
      Foo &fooRef = foo;
      Foo *fooPtr = &foo;

A Block that referenced these variables would import the variables as
const variations:

.. code-block:: c

      const Foo block_foo = foo;
      Foo &block_fooRef = fooRef;
      Foo *const block_fooPtr = fooPtr;

Captured variables are copied into the Block at the instant of
evaluating the Block literal expression.  They are also copied when
calling ``Block_copy()`` on a Block allocated on the stack.  In both
cases, they are copied as if the variable were const-qualified, and
it's an error if there's no such constructor.

Captured variables in Blocks on the stack are destroyed when control
leaves the compound statement that contains the Block literal
expression.  Captured variables in Blocks on the heap are destroyed
when the reference count of the Block drops to zero.

Variables declared as residing in ``__block`` storage may be initially
allocated in the heap or may first appear on the stack and be copied
to the heap as a result of a ``Block_copy()`` operation. When copied
from the stack, ``__block`` variables are copied using their normal
qualification (i.e. without adding const).  In C++11, ``__block``
variables are copied as x-values if that is possible, then as l-values
if not; if both fail, it's an error.  The destructor for any initial
stack-based version is called at the variable's normal end of scope.

References to ``this``, as well as references to non-static members of
any enclosing class, are evaluated by capturing ``this`` just like a
normal variable of C pointer type.

Member variables that are Blocks may not be overloaded by the types of
their arguments.