annotate clang/docs/BlockLanguageSpec.rst @ 176:de4ac79aef9d

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 17:13:11 +0900
parents 1d019706d866
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1
anatofuz
parents:
diff changeset
2 .. role:: block-term
anatofuz
parents:
diff changeset
3
anatofuz
parents:
diff changeset
4 =================================
anatofuz
parents:
diff changeset
5 Language Specification for Blocks
anatofuz
parents:
diff changeset
6 =================================
anatofuz
parents:
diff changeset
7
anatofuz
parents:
diff changeset
8 .. contents::
anatofuz
parents:
diff changeset
9 :local:
anatofuz
parents:
diff changeset
10
anatofuz
parents:
diff changeset
11 Revisions
anatofuz
parents:
diff changeset
12 =========
anatofuz
parents:
diff changeset
13
anatofuz
parents:
diff changeset
14 - 2008/2/25 --- created
anatofuz
parents:
diff changeset
15 - 2008/7/28 --- revised, ``__block`` syntax
anatofuz
parents:
diff changeset
16 - 2008/8/13 --- revised, Block globals
anatofuz
parents:
diff changeset
17 - 2008/8/21 --- revised, C++ elaboration
anatofuz
parents:
diff changeset
18 - 2008/11/1 --- revised, ``__weak`` support
anatofuz
parents:
diff changeset
19 - 2009/1/12 --- revised, explicit return types
anatofuz
parents:
diff changeset
20 - 2009/2/10 --- revised, ``__block`` objects need retain
anatofuz
parents:
diff changeset
21
anatofuz
parents:
diff changeset
22 Overview
anatofuz
parents:
diff changeset
23 ========
anatofuz
parents:
diff changeset
24
anatofuz
parents:
diff changeset
25 A new derived type is introduced to C and, by extension, Objective-C,
anatofuz
parents:
diff changeset
26 C++, and Objective-C++
anatofuz
parents:
diff changeset
27
anatofuz
parents:
diff changeset
28 The Block Type
anatofuz
parents:
diff changeset
29 ==============
anatofuz
parents:
diff changeset
30
anatofuz
parents:
diff changeset
31 Like function types, the :block-term:`Block type` is a pair consisting
anatofuz
parents:
diff changeset
32 of a result value type and a list of parameter types very similar to a
anatofuz
parents:
diff changeset
33 function type. Blocks are intended to be used much like functions with
anatofuz
parents:
diff changeset
34 the key distinction being that in addition to executable code they
anatofuz
parents:
diff changeset
35 also contain various variable bindings to automatic (stack) or managed
anatofuz
parents:
diff changeset
36 (heap) memory.
anatofuz
parents:
diff changeset
37
anatofuz
parents:
diff changeset
38 The abstract declarator,
anatofuz
parents:
diff changeset
39
anatofuz
parents:
diff changeset
40 .. code-block:: c
anatofuz
parents:
diff changeset
41
anatofuz
parents:
diff changeset
42 int (^)(char, float)
anatofuz
parents:
diff changeset
43
anatofuz
parents:
diff changeset
44 describes a reference to a Block that, when invoked, takes two
anatofuz
parents:
diff changeset
45 parameters, the first of type char and the second of type float, and
anatofuz
parents:
diff changeset
46 returns a value of type int. The Block referenced is of opaque data
anatofuz
parents:
diff changeset
47 that may reside in automatic (stack) memory, global memory, or heap
anatofuz
parents:
diff changeset
48 memory.
anatofuz
parents:
diff changeset
49
anatofuz
parents:
diff changeset
50 Block Variable Declarations
anatofuz
parents:
diff changeset
51 ===========================
anatofuz
parents:
diff changeset
52
anatofuz
parents:
diff changeset
53 A :block-term:`variable with Block type` is declared using function
anatofuz
parents:
diff changeset
54 pointer style notation substituting ``^`` for ``*``. The following are
anatofuz
parents:
diff changeset
55 valid Block variable declarations:
anatofuz
parents:
diff changeset
56
anatofuz
parents:
diff changeset
57 .. code-block:: c
anatofuz
parents:
diff changeset
58
anatofuz
parents:
diff changeset
59 void (^blockReturningVoidWithVoidArgument)(void);
anatofuz
parents:
diff changeset
60 int (^blockReturningIntWithIntAndCharArguments)(int, char);
anatofuz
parents:
diff changeset
61 void (^arrayOfTenBlocksReturningVoidWithIntArgument[10])(int);
anatofuz
parents:
diff changeset
62
anatofuz
parents:
diff changeset
63 Variadic ``...`` arguments are supported. [variadic.c] A Block that
anatofuz
parents:
diff changeset
64 takes no arguments must specify void in the argument list [voidarg.c].
anatofuz
parents:
diff changeset
65 An empty parameter list does not represent, as K&R provide, an
anatofuz
parents:
diff changeset
66 unspecified argument list. Note: both gcc and clang support K&R style
anatofuz
parents:
diff changeset
67 as a convenience.
anatofuz
parents:
diff changeset
68
anatofuz
parents:
diff changeset
69 A Block reference may be cast to a pointer of arbitrary type and vice
anatofuz
parents:
diff changeset
70 versa. [cast.c] A Block reference may not be dereferenced via the
anatofuz
parents:
diff changeset
71 pointer dereference operator ``*``, and thus a Block's size may not be
anatofuz
parents:
diff changeset
72 computed at compile time. [sizeof.c]
anatofuz
parents:
diff changeset
73
anatofuz
parents:
diff changeset
74 Block Literal Expressions
anatofuz
parents:
diff changeset
75 =========================
anatofuz
parents:
diff changeset
76
anatofuz
parents:
diff changeset
77 A :block-term:`Block literal expression` produces a reference to a
anatofuz
parents:
diff changeset
78 Block. It is introduced by the use of the ``^`` token as a unary
anatofuz
parents:
diff changeset
79 operator.
anatofuz
parents:
diff changeset
80
anatofuz
parents:
diff changeset
81 .. code-block:: c
anatofuz
parents:
diff changeset
82
anatofuz
parents:
diff changeset
83 Block_literal_expression ::= ^ block_decl compound_statement_body
anatofuz
parents:
diff changeset
84 block_decl ::=
anatofuz
parents:
diff changeset
85 block_decl ::= parameter_list
anatofuz
parents:
diff changeset
86 block_decl ::= type_expression
anatofuz
parents:
diff changeset
87
anatofuz
parents:
diff changeset
88 where type expression is extended to allow ``^`` as a Block reference
anatofuz
parents:
diff changeset
89 (pointer) where ``*`` is allowed as a function reference (pointer).
anatofuz
parents:
diff changeset
90
anatofuz
parents:
diff changeset
91 The following Block literal:
anatofuz
parents:
diff changeset
92
anatofuz
parents:
diff changeset
93 .. code-block:: c
anatofuz
parents:
diff changeset
94
anatofuz
parents:
diff changeset
95 ^ void (void) { printf("hello world\n"); }
anatofuz
parents:
diff changeset
96
anatofuz
parents:
diff changeset
97 produces a reference to a Block with no arguments with no return value.
anatofuz
parents:
diff changeset
98
anatofuz
parents:
diff changeset
99 The return type is optional and is inferred from the return
anatofuz
parents:
diff changeset
100 statements. If the return statements return a value, they all must
anatofuz
parents:
diff changeset
101 return a value of the same type. If there is no value returned the
anatofuz
parents:
diff changeset
102 inferred type of the Block is void; otherwise it is the type of the
anatofuz
parents:
diff changeset
103 return statement value.
anatofuz
parents:
diff changeset
104
anatofuz
parents:
diff changeset
105 If the return type is omitted and the argument list is ``( void )``,
anatofuz
parents:
diff changeset
106 the ``( void )`` argument list may also be omitted.
anatofuz
parents:
diff changeset
107
anatofuz
parents:
diff changeset
108 So:
anatofuz
parents:
diff changeset
109
anatofuz
parents:
diff changeset
110 .. code-block:: c
anatofuz
parents:
diff changeset
111
anatofuz
parents:
diff changeset
112 ^ ( void ) { printf("hello world\n"); }
anatofuz
parents:
diff changeset
113
anatofuz
parents:
diff changeset
114 and:
anatofuz
parents:
diff changeset
115
anatofuz
parents:
diff changeset
116 .. code-block:: c
anatofuz
parents:
diff changeset
117
anatofuz
parents:
diff changeset
118 ^ { printf("hello world\n"); }
anatofuz
parents:
diff changeset
119
anatofuz
parents:
diff changeset
120 are exactly equivalent constructs for the same expression.
anatofuz
parents:
diff changeset
121
anatofuz
parents:
diff changeset
122 The type_expression extends C expression parsing to accommodate Block
anatofuz
parents:
diff changeset
123 reference declarations as it accommodates function pointer
anatofuz
parents:
diff changeset
124 declarations.
anatofuz
parents:
diff changeset
125
anatofuz
parents:
diff changeset
126 Given:
anatofuz
parents:
diff changeset
127
anatofuz
parents:
diff changeset
128 .. code-block:: c
anatofuz
parents:
diff changeset
129
anatofuz
parents:
diff changeset
130 typedef int (*pointerToFunctionThatReturnsIntWithCharArg)(char);
anatofuz
parents:
diff changeset
131 pointerToFunctionThatReturnsIntWithCharArg functionPointer;
anatofuz
parents:
diff changeset
132 ^ pointerToFunctionThatReturnsIntWithCharArg (float x) { return functionPointer; }
anatofuz
parents:
diff changeset
133
anatofuz
parents:
diff changeset
134 and:
anatofuz
parents:
diff changeset
135
anatofuz
parents:
diff changeset
136 .. code-block:: c
anatofuz
parents:
diff changeset
137
anatofuz
parents:
diff changeset
138 ^ int ((*)(float x))(char) { return functionPointer; }
anatofuz
parents:
diff changeset
139
anatofuz
parents:
diff changeset
140 are equivalent expressions, as is:
anatofuz
parents:
diff changeset
141
anatofuz
parents:
diff changeset
142 .. code-block:: c
anatofuz
parents:
diff changeset
143
anatofuz
parents:
diff changeset
144 ^(float x) { return functionPointer; }
anatofuz
parents:
diff changeset
145
anatofuz
parents:
diff changeset
146 [returnfunctionptr.c]
anatofuz
parents:
diff changeset
147
anatofuz
parents:
diff changeset
148 The compound statement body establishes a new lexical scope within
anatofuz
parents:
diff changeset
149 that of its parent. Variables used within the scope of the compound
anatofuz
parents:
diff changeset
150 statement are bound to the Block in the normal manner with the
anatofuz
parents:
diff changeset
151 exception of those in automatic (stack) storage. Thus one may access
anatofuz
parents:
diff changeset
152 functions and global variables as one would expect, as well as static
anatofuz
parents:
diff changeset
153 local variables. [testme]
anatofuz
parents:
diff changeset
154
anatofuz
parents:
diff changeset
155 Local automatic (stack) variables referenced within the compound
anatofuz
parents:
diff changeset
156 statement of a Block are imported and captured by the Block as const
anatofuz
parents:
diff changeset
157 copies. The capture (binding) is performed at the time of the Block
anatofuz
parents:
diff changeset
158 literal expression evaluation.
anatofuz
parents:
diff changeset
159
anatofuz
parents:
diff changeset
160 The compiler is not required to capture a variable if it can prove
anatofuz
parents:
diff changeset
161 that no references to the variable will actually be evaluated.
anatofuz
parents:
diff changeset
162 Programmers can force a variable to be captured by referencing it in a
anatofuz
parents:
diff changeset
163 statement at the beginning of the Block, like so:
anatofuz
parents:
diff changeset
164
anatofuz
parents:
diff changeset
165 .. code-block:: c
anatofuz
parents:
diff changeset
166
anatofuz
parents:
diff changeset
167 (void) foo;
anatofuz
parents:
diff changeset
168
anatofuz
parents:
diff changeset
169 This matters when capturing the variable has side-effects, as it can
anatofuz
parents:
diff changeset
170 in Objective-C or C++.
anatofuz
parents:
diff changeset
171
anatofuz
parents:
diff changeset
172 The lifetime of variables declared in a Block is that of a function;
anatofuz
parents:
diff changeset
173 each activation frame contains a new copy of variables declared within
anatofuz
parents:
diff changeset
174 the local scope of the Block. Such variable declarations should be
anatofuz
parents:
diff changeset
175 allowed anywhere [testme] rather than only when C99 parsing is
anatofuz
parents:
diff changeset
176 requested, including for statements. [testme]
anatofuz
parents:
diff changeset
177
anatofuz
parents:
diff changeset
178 Block literal expressions may occur within Block literal expressions
anatofuz
parents:
diff changeset
179 (nest) and all variables captured by any nested blocks are implicitly
anatofuz
parents:
diff changeset
180 also captured in the scopes of their enclosing Blocks.
anatofuz
parents:
diff changeset
181
anatofuz
parents:
diff changeset
182 A Block literal expression may be used as the initialization value for
anatofuz
parents:
diff changeset
183 Block variables at global or local static scope.
anatofuz
parents:
diff changeset
184
anatofuz
parents:
diff changeset
185 The Invoke Operator
anatofuz
parents:
diff changeset
186 ===================
anatofuz
parents:
diff changeset
187
anatofuz
parents:
diff changeset
188 Blocks are :block-term:`invoked` using function call syntax with a
anatofuz
parents:
diff changeset
189 list of expression parameters of types corresponding to the
anatofuz
parents:
diff changeset
190 declaration and returning a result type also according to the
anatofuz
parents:
diff changeset
191 declaration. Given:
anatofuz
parents:
diff changeset
192
anatofuz
parents:
diff changeset
193 .. code-block:: c
anatofuz
parents:
diff changeset
194
anatofuz
parents:
diff changeset
195 int (^x)(char);
anatofuz
parents:
diff changeset
196 void (^z)(void);
anatofuz
parents:
diff changeset
197 int (^(*y))(char) = &x;
anatofuz
parents:
diff changeset
198
anatofuz
parents:
diff changeset
199 the following are all legal Block invocations:
anatofuz
parents:
diff changeset
200
anatofuz
parents:
diff changeset
201 .. code-block:: c
anatofuz
parents:
diff changeset
202
anatofuz
parents:
diff changeset
203 x('a');
anatofuz
parents:
diff changeset
204 (*y)('a');
anatofuz
parents:
diff changeset
205 (true ? x : *y)('a')
anatofuz
parents:
diff changeset
206
anatofuz
parents:
diff changeset
207 The Copy and Release Operations
anatofuz
parents:
diff changeset
208 ===============================
anatofuz
parents:
diff changeset
209
anatofuz
parents:
diff changeset
210 The compiler and runtime provide :block-term:`copy` and
anatofuz
parents:
diff changeset
211 :block-term:`release` operations for Block references that create and,
anatofuz
parents:
diff changeset
212 in matched use, release allocated storage for referenced Blocks.
anatofuz
parents:
diff changeset
213
anatofuz
parents:
diff changeset
214 The copy operation ``Block_copy()`` is styled as a function that takes
anatofuz
parents:
diff changeset
215 an arbitrary Block reference and returns a Block reference of the same
anatofuz
parents:
diff changeset
216 type. The release operation, ``Block_release()``, is styled as a
anatofuz
parents:
diff changeset
217 function that takes an arbitrary Block reference and, if dynamically
anatofuz
parents:
diff changeset
218 matched to a Block copy operation, allows recovery of the referenced
anatofuz
parents:
diff changeset
219 allocated memory.
anatofuz
parents:
diff changeset
220
anatofuz
parents:
diff changeset
221
anatofuz
parents:
diff changeset
222 The ``__block`` Storage Qualifier
anatofuz
parents:
diff changeset
223 =================================
anatofuz
parents:
diff changeset
224
anatofuz
parents:
diff changeset
225 In addition to the new Block type we also introduce a new storage
anatofuz
parents:
diff changeset
226 qualifier, :block-term:`__block`, for local variables. [testme: a
anatofuz
parents:
diff changeset
227 __block declaration within a block literal] The ``__block`` storage
anatofuz
parents:
diff changeset
228 qualifier is mutually exclusive to the existing local storage
anatofuz
parents:
diff changeset
229 qualifiers auto, register, and static. [testme] Variables qualified by
anatofuz
parents:
diff changeset
230 ``__block`` act as if they were in allocated storage and this storage
anatofuz
parents:
diff changeset
231 is automatically recovered after last use of said variable. An
anatofuz
parents:
diff changeset
232 implementation may choose an optimization where the storage is
anatofuz
parents:
diff changeset
233 initially automatic and only "moved" to allocated (heap) storage upon
anatofuz
parents:
diff changeset
234 a Block_copy of a referencing Block. Such variables may be mutated as
anatofuz
parents:
diff changeset
235 normal variables are.
anatofuz
parents:
diff changeset
236
anatofuz
parents:
diff changeset
237 In the case where a ``__block`` variable is a Block one must assume
anatofuz
parents:
diff changeset
238 that the ``__block`` variable resides in allocated storage and as such
anatofuz
parents:
diff changeset
239 is assumed to reference a Block that is also in allocated storage
anatofuz
parents:
diff changeset
240 (that it is the result of a ``Block_copy`` operation). Despite this
anatofuz
parents:
diff changeset
241 there is no provision to do a ``Block_copy`` or a ``Block_release`` if
anatofuz
parents:
diff changeset
242 an implementation provides initial automatic storage for Blocks. This
anatofuz
parents:
diff changeset
243 is due to the inherent race condition of potentially several threads
anatofuz
parents:
diff changeset
244 trying to update the shared variable and the need for synchronization
anatofuz
parents:
diff changeset
245 around disposing of older values and copying new ones. Such
anatofuz
parents:
diff changeset
246 synchronization is beyond the scope of this language specification.
anatofuz
parents:
diff changeset
247
anatofuz
parents:
diff changeset
248
anatofuz
parents:
diff changeset
249 Control Flow
anatofuz
parents:
diff changeset
250 ============
anatofuz
parents:
diff changeset
251
anatofuz
parents:
diff changeset
252 The compound statement of a Block is treated much like a function body
anatofuz
parents:
diff changeset
253 with respect to control flow in that goto, break, and continue do not
anatofuz
parents:
diff changeset
254 escape the Block. Exceptions are treated *normally* in that when
anatofuz
parents:
diff changeset
255 thrown they pop stack frames until a catch clause is found.
anatofuz
parents:
diff changeset
256
anatofuz
parents:
diff changeset
257
anatofuz
parents:
diff changeset
258 Objective-C Extensions
anatofuz
parents:
diff changeset
259 ======================
anatofuz
parents:
diff changeset
260
anatofuz
parents:
diff changeset
261 Objective-C extends the definition of a Block reference type to be
anatofuz
parents:
diff changeset
262 that also of id. A variable or expression of Block type may be
anatofuz
parents:
diff changeset
263 messaged or used as a parameter wherever an id may be. The converse is
anatofuz
parents:
diff changeset
264 also true. Block references may thus appear as properties and are
anatofuz
parents:
diff changeset
265 subject to the assign, retain, and copy attribute logic that is
anatofuz
parents:
diff changeset
266 reserved for objects.
anatofuz
parents:
diff changeset
267
anatofuz
parents:
diff changeset
268 All Blocks are constructed to be Objective-C objects regardless of
anatofuz
parents:
diff changeset
269 whether the Objective-C runtime is operational in the program or
anatofuz
parents:
diff changeset
270 not. Blocks using automatic (stack) memory are objects and may be
anatofuz
parents:
diff changeset
271 messaged, although they may not be assigned into ``__weak`` locations
anatofuz
parents:
diff changeset
272 if garbage collection is enabled.
anatofuz
parents:
diff changeset
273
anatofuz
parents:
diff changeset
274 Within a Block literal expression within a method definition
anatofuz
parents:
diff changeset
275 references to instance variables are also imported into the lexical
anatofuz
parents:
diff changeset
276 scope of the compound statement. These variables are implicitly
anatofuz
parents:
diff changeset
277 qualified as references from self, and so self is imported as a const
anatofuz
parents:
diff changeset
278 copy. The net effect is that instance variables can be mutated.
anatofuz
parents:
diff changeset
279
anatofuz
parents:
diff changeset
280 The :block-term:`Block_copy` operator retains all objects held in
anatofuz
parents:
diff changeset
281 variables of automatic storage referenced within the Block expression
anatofuz
parents:
diff changeset
282 (or form strong references if running under garbage collection).
anatofuz
parents:
diff changeset
283 Object variables of ``__block`` storage type are assumed to hold
anatofuz
parents:
diff changeset
284 normal pointers with no provision for retain and release messages.
anatofuz
parents:
diff changeset
285
anatofuz
parents:
diff changeset
286 Foundation defines (and supplies) ``-copy`` and ``-release`` methods for
anatofuz
parents:
diff changeset
287 Blocks.
anatofuz
parents:
diff changeset
288
anatofuz
parents:
diff changeset
289 In the Objective-C and Objective-C++ languages, we allow the
anatofuz
parents:
diff changeset
290 ``__weak`` specifier for ``__block`` variables of object type. If
anatofuz
parents:
diff changeset
291 garbage collection is not enabled, this qualifier causes these
anatofuz
parents:
diff changeset
292 variables to be kept without retain messages being sent. This
anatofuz
parents:
diff changeset
293 knowingly leads to dangling pointers if the Block (or a copy) outlives
anatofuz
parents:
diff changeset
294 the lifetime of this object.
anatofuz
parents:
diff changeset
295
anatofuz
parents:
diff changeset
296 In garbage collected environments, the ``__weak`` variable is set to
anatofuz
parents:
diff changeset
297 nil when the object it references is collected, as long as the
anatofuz
parents:
diff changeset
298 ``__block`` variable resides in the heap (either by default or via
anatofuz
parents:
diff changeset
299 ``Block_copy()``). The initial Apple implementation does in fact
anatofuz
parents:
diff changeset
300 start ``__block`` variables on the stack and migrate them to the heap
anatofuz
parents:
diff changeset
301 only as a result of a ``Block_copy()`` operation.
anatofuz
parents:
diff changeset
302
anatofuz
parents:
diff changeset
303 It is a runtime error to attempt to assign a reference to a
anatofuz
parents:
diff changeset
304 stack-based Block into any storage marked ``__weak``, including
anatofuz
parents:
diff changeset
305 ``__weak`` ``__block`` variables.
anatofuz
parents:
diff changeset
306
anatofuz
parents:
diff changeset
307
anatofuz
parents:
diff changeset
308 C++ Extensions
anatofuz
parents:
diff changeset
309 ==============
anatofuz
parents:
diff changeset
310
anatofuz
parents:
diff changeset
311 Block literal expressions within functions are extended to allow const
anatofuz
parents:
diff changeset
312 use of C++ objects, pointers, or references held in automatic storage.
anatofuz
parents:
diff changeset
313
anatofuz
parents:
diff changeset
314 As usual, within the block, references to captured variables become
anatofuz
parents:
diff changeset
315 const-qualified, as if they were references to members of a const
anatofuz
parents:
diff changeset
316 object. Note that this does not change the type of a variable of
anatofuz
parents:
diff changeset
317 reference type.
anatofuz
parents:
diff changeset
318
anatofuz
parents:
diff changeset
319 For example, given a class Foo:
anatofuz
parents:
diff changeset
320
anatofuz
parents:
diff changeset
321 .. code-block:: c
anatofuz
parents:
diff changeset
322
anatofuz
parents:
diff changeset
323 Foo foo;
anatofuz
parents:
diff changeset
324 Foo &fooRef = foo;
anatofuz
parents:
diff changeset
325 Foo *fooPtr = &foo;
anatofuz
parents:
diff changeset
326
anatofuz
parents:
diff changeset
327 A Block that referenced these variables would import the variables as
anatofuz
parents:
diff changeset
328 const variations:
anatofuz
parents:
diff changeset
329
anatofuz
parents:
diff changeset
330 .. code-block:: c
anatofuz
parents:
diff changeset
331
anatofuz
parents:
diff changeset
332 const Foo block_foo = foo;
anatofuz
parents:
diff changeset
333 Foo &block_fooRef = fooRef;
anatofuz
parents:
diff changeset
334 Foo *const block_fooPtr = fooPtr;
anatofuz
parents:
diff changeset
335
anatofuz
parents:
diff changeset
336 Captured variables are copied into the Block at the instant of
anatofuz
parents:
diff changeset
337 evaluating the Block literal expression. They are also copied when
anatofuz
parents:
diff changeset
338 calling ``Block_copy()`` on a Block allocated on the stack. In both
anatofuz
parents:
diff changeset
339 cases, they are copied as if the variable were const-qualified, and
anatofuz
parents:
diff changeset
340 it's an error if there's no such constructor.
anatofuz
parents:
diff changeset
341
anatofuz
parents:
diff changeset
342 Captured variables in Blocks on the stack are destroyed when control
anatofuz
parents:
diff changeset
343 leaves the compound statement that contains the Block literal
anatofuz
parents:
diff changeset
344 expression. Captured variables in Blocks on the heap are destroyed
anatofuz
parents:
diff changeset
345 when the reference count of the Block drops to zero.
anatofuz
parents:
diff changeset
346
anatofuz
parents:
diff changeset
347 Variables declared as residing in ``__block`` storage may be initially
anatofuz
parents:
diff changeset
348 allocated in the heap or may first appear on the stack and be copied
anatofuz
parents:
diff changeset
349 to the heap as a result of a ``Block_copy()`` operation. When copied
anatofuz
parents:
diff changeset
350 from the stack, ``__block`` variables are copied using their normal
anatofuz
parents:
diff changeset
351 qualification (i.e. without adding const). In C++11, ``__block``
anatofuz
parents:
diff changeset
352 variables are copied as x-values if that is possible, then as l-values
anatofuz
parents:
diff changeset
353 if not; if both fail, it's an error. The destructor for any initial
anatofuz
parents:
diff changeset
354 stack-based version is called at the variable's normal end of scope.
anatofuz
parents:
diff changeset
355
anatofuz
parents:
diff changeset
356 References to ``this``, as well as references to non-static members of
anatofuz
parents:
diff changeset
357 any enclosing class, are evaluated by capturing ``this`` just like a
anatofuz
parents:
diff changeset
358 normal variable of C pointer type.
anatofuz
parents:
diff changeset
359
anatofuz
parents:
diff changeset
360 Member variables that are Blocks may not be overloaded by the types of
anatofuz
parents:
diff changeset
361 their arguments.