<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"><channel><title>mikeash.com pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html comments</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>mikeash.com Recent Comments</description><lastBuildDate>Mon, 17 Aug 2026 11:21:58 GMT</lastBuildDate><generator>PyRSS2Gen-1.0.0</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>santhosh - 2014-02-25 12:01:44</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>Thanks guys. Not only i learned much from the article, but a great deal from comments. I should fix some of my projects.thanks again.</description><guid isPermaLink="true">63b2a19d593d1028d8ffe828efa7acce</guid><pubDate>Tue, 25 Feb 2014 12:01:44 GMT</pubDate></item><item><title>Gabriele - 2012-07-31 16:57:30</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>Thanks a lot for your post.
&lt;br /&gt;FYI, when using __bridge_retained on blocks that are on the stack, with Xcode 4.4, O3, ARC, the compiler does neither retain nor copy the block... Good source of bugs :-)</description><guid isPermaLink="true">9f80ddcb6eb3d323482c3ff731c790f7</guid><pubDate>Tue, 31 Jul 2012 16:57:30 GMT</pubDate></item><item><title>Louis Gerbarg - 2010-01-26 15:39:24</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>If you directly invoke clang-cc you can actually see what the rewritten code looks like. The rewriter actually generates C++ code so that it can directly embed the anon functions inside a struct that represents its scope. Obviously the actual compiler doesn't do it quite that way internally, it is just the most sensible way to emit ASTs with block contexts in them as code that doesn't depend on blocks. For a concrete example:
&lt;br /&gt;
&lt;br /&gt;//With blocks and libdispatch
&lt;br /&gt;
&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;
&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;
&lt;br /&gt;#include &amp;lt;stdint.h&amp;gt;
&lt;br /&gt;#include &amp;lt;inttypes.h&amp;gt;
&lt;br /&gt;
&lt;br /&gt;#include &amp;lt;dispatch/dispatch.h&amp;gt;
&lt;br /&gt;
&lt;br /&gt;//We add a completion handler that gets called when all the work is down,
&lt;br /&gt;//it is just another block
&lt;br /&gt;
&lt;br /&gt;void call_100_times(void (^callback)(void), void (^completion)(void)) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;uint32_t i;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;for (i = 0; i &amp;lt; 100; i++) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dispatch_async(queue, callback);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;dispatch_async(queue, completion);
&lt;br /&gt;}
&lt;br /&gt;
&lt;br /&gt;int main(void) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;__block volatile uint32_t i = 0;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;dispatch_queue_t main_queue = dispatch_get_main_queue();
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;call_100_times(^{
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Issue an asynch printf from whatever queue we are on to the main queue
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dispatch_async(main_queue, ^{
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32_t incremented_value = __sync_add_and_fetch(&amp;amp;i, 1);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf("Out: %" PRIu32 "\n", incremented_value - 1);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
&lt;br /&gt;&amp;nbsp;&amp;nbsp;},
&lt;br /&gt;&amp;nbsp;&amp;nbsp;^{
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Need to explicitly call exit now that the end of main is never reached
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//We do it here in the completion block
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dispatch_async(main_queue, ^{
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;exit(0);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
&lt;br /&gt;&amp;nbsp;&amp;nbsp;});
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;//Start the dispatcher
&lt;br /&gt;&amp;nbsp;&amp;nbsp;dispatch_main();
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;//NOT REACHED
&lt;br /&gt;}
&lt;br /&gt;
&lt;br /&gt;Gets rewritten as:
&lt;br /&gt;
&lt;br /&gt;#ifndef BLOCK_IMPL
&lt;br /&gt;#define BLOCK_IMPL
&lt;br /&gt;struct __block_impl {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;void *isa;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;int Flags;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;int Size;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;void *FuncPtr;
&lt;br /&gt;};
&lt;br /&gt;enum {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;BLOCK_HAS_COPY_DISPOSE = (1&amp;lt;&amp;lt;25),
&lt;br /&gt;&amp;nbsp;&amp;nbsp;BLOCK_IS_GLOBAL = (1&amp;lt;&amp;lt;28)
&lt;br /&gt;};
&lt;br /&gt;#define __OBJC_RW_EXTERN extern
&lt;br /&gt;// Runtime copy/destroy helper functions
&lt;br /&gt;__OBJC_RW_EXTERN void _Block_copy_assign(void *, void *);
&lt;br /&gt;__OBJC_RW_EXTERN void _Block_byref_assign_copy(void *, void *);
&lt;br /&gt;__OBJC_RW_EXTERN void _Block_destroy(void *);
&lt;br /&gt;__OBJC_RW_EXTERN void _Block_byref_release(void *);
&lt;br /&gt;__OBJC_RW_EXTERN void *_NSConcreteGlobalBlock;
&lt;br /&gt;__OBJC_RW_EXTERN void *_NSConcreteStackBlock;
&lt;br /&gt;#endif
&lt;br /&gt;//With blocks and libdispatch
&lt;br /&gt;
&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;
&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;
&lt;br /&gt;#include &amp;lt;stdint.h&amp;gt;
&lt;br /&gt;#include &amp;lt;inttypes.h&amp;gt;
&lt;br /&gt;
&lt;br /&gt;#include &amp;lt;dispatch/dispatch.h&amp;gt;
&lt;br /&gt;
&lt;br /&gt;//We add a completion handler that gets called when all the work is down,
&lt;br /&gt;//it is just another block
&lt;br /&gt;
&lt;br /&gt;void call_100_times(void (*callback)(void), void (^comple*ion)(void)) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;uint32_t i;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;for (i = 0; i &amp;lt; 100; i++) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dispatch_async(queue, callback);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;dispatch_async(queue, completion);
&lt;br /&gt;}
&lt;br /&gt;
&lt;br /&gt;struct __main_block_impl_0 {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;struct __block_impl impl;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;uint32_t volatile *i; // by ref
&lt;br /&gt;&amp;nbsp;&amp;nbsp;__main_block_impl_0(void *fp, uint32_t volatile *_i, int flags=0) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;impl.isa = 0/*&amp;amp;_NSConcreteStackBlock*/;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;impl.Size = sizeof(__main_block_impl_0);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;impl.Flags = flags;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;impl.FuncPtr = fp;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;i = _i;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;};
&lt;br /&gt;static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;uint32_t volatile *i = __cself-&amp;gt;i; // bound by ref
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;uint32_t incremented_value = __sync_add_and_fetch(&amp;amp;*i, 1);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf("Out: %" PRIu32 "\n", incremented_value - 1);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;struct __main_block_impl_1 {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;struct __block_impl impl;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;dispatch_queue_t main_queue;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;uint32_t volatile *i; // by ref
&lt;br /&gt;&amp;nbsp;&amp;nbsp;__main_block_impl_1(void *fp, dispatch_queue_t _main_queue, uint32_t volatile *_i, int flags=0) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;impl.isa = 0/*&amp;amp;_NSConcreteStackBlock*/;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;impl.Size = sizeof(__main_block_impl_1);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;impl.Flags = flags;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;impl.FuncPtr = fp;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;main_queue = _main_queue;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;i = _i;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;};
&lt;br /&gt;static void __main_block_func_1(struct __main_block_impl_1 *__cself) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;uint32_t volatile *i = __cself-&amp;gt;i; // bound by ref
&lt;br /&gt;&amp;nbsp;&amp;nbsp;dispatch_queue_t main_queue = __cself-&amp;gt;main_queue; // bound by copy
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Issue an asynch printf from whatever queue we are on to the main queue
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dispatch_async(main_queue, (void (*)(void))&amp;amp;__main_block_impl_0((void*)__main_block_func_0,&amp;amp;i));
&lt;br /&gt;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;struct __main_block_impl_2 {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;struct __block_impl impl;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;__main_block_impl_2(void *fp, int flags=0) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;impl.isa = 0/*&amp;amp;_NSConcreteStackBlock*/;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;impl.Size = sizeof(__main_block_impl_2);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;impl.Flags = flags;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;impl.FuncPtr = fp;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;};
&lt;br /&gt;static void __main_block_func_2(struct __main_block_impl_2 *__cself) {
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;exit(0);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;struct __main_block_impl_3 {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;struct __block_impl impl;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;dispatch_queue_t main_queue;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;__main_block_impl_3(void *fp, dispatch_queue_t _main_queue, int flags=0) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;impl.isa = 0/*&amp;amp;_NSConcreteStackBlock*/;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;impl.Size = sizeof(__main_block_impl_3);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;impl.Flags = flags;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;impl.FuncPtr = fp;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;main_queue = _main_queue;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;};
&lt;br /&gt;static void __main_block_func_3(struct __main_block_impl_3 *__cself) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;dispatch_queue_t main_queue = __cself-&amp;gt;main_queue; // bound by copy
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Need to explicitly call exit now that the end of main is never reached
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//We do it here in the completion block
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dispatch_async(main_queue, (void (*)(void))&amp;amp;__main_block_impl_2((void*)__main_block_func_2));
&lt;br /&gt;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;int main(void) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;__block volatile uint32_t i = 0;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;dispatch_queue_t main_queue = dispatch_get_main_queue();
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;call_100_times((void (*)(void))&amp;amp;__main_block_impl_1((void*)__main_block_func_1,main_queue,&amp;amp;i),
&lt;br /&gt;&amp;nbsp;&amp;nbsp;(void (*)(void))&amp;amp;__main_block_impl_3((void*)__main_block_func_3,main_queue));
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;//Start the dispatcher
&lt;br /&gt;&amp;nbsp;&amp;nbsp;dispatch_main();
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;//NOT REACHED
&lt;br /&gt;}
&lt;br /&gt;
&lt;br /&gt;</description><guid isPermaLink="true">592e6650b6a4d977ee1044993d90bfd7</guid><pubDate>Tue, 26 Jan 2010 15:39:24 GMT</pubDate></item><item><title>mikeash - 2010-01-25 22:52:34</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>Yep, that's pretty much it. Like you say it's grossly simplified, but the essential aspect that it just creates a struct on the stack and fills it out is just what happens in real code.</description><guid isPermaLink="true">9aa09014c7a363eaca08f5d0c4382840</guid><pubDate>Mon, 25 Jan 2010 22:52:34 GMT</pubDate></item><item><title>Jason - 2010-01-25 12:33:47</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>Mike,
&lt;br /&gt;
&lt;br /&gt;Thanks for the clarification. This helps a lot. It may also be helpful to explain (in pseudocode) what exactly the compiler is doing (much like explaining how Obj-C messages get transformed into objc_msgSend calls)..
&lt;br /&gt;
&lt;br /&gt;Does it essentially take something like this:
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;void (^block[10])();
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int i = -1;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while(++i &amp;lt; 10)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block[i] = ^{ printf("%d\n", i); };
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for(i = 0; i &amp;lt; 10; i++)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block[i](); 
&lt;br /&gt;
&lt;br /&gt;And turn it into this:
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;anonymous_method_1(NSBlock * state)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf("%d\n", state-&amp;gt;vars-&amp;gt;i);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NSBlock *block[10];
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int i = -1;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while(++i &amp;lt; 10) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NSBlock the_block; // stack allocated
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// ... capture i into the_block
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;the_block.imp = anonymous_method_1;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block[i] = &amp;amp;the_block;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for(i = 0; i &amp;lt; 10; i++)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block[i]-&amp;gt;imp(); 
&lt;br /&gt;
&lt;br /&gt;Grossly simplified, of course, but it sounds like this is what happens internally.
&lt;br /&gt;
&lt;br /&gt;</description><guid isPermaLink="true">57fa347b78dced919e8e3443756dd27a</guid><pubDate>Mon, 25 Jan 2010 12:33:47 GMT</pubDate></item><item><title>mikeash - 2010-01-25 01:45:47</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>No it doesn't. If that were the case, then the behavior wouldn't change when you copy the block. (Copying the block is &lt;i&gt;purely&lt;/i&gt; an act of memory management. In correct code, copying a block will never change behavior.)
&lt;br /&gt;
&lt;br /&gt;Did you try your proposed modification? It &lt;i&gt;still&lt;/i&gt; prints out ten 9s....
&lt;br /&gt;
&lt;br /&gt;Blocks in Objective-C &lt;i&gt;always&lt;/i&gt; grab a "local copy" of all closed-over local variables, unless you explicitly request otherwise by qualifying the declaration with the &lt;code&gt;__block&lt;/code&gt; qualifier.
&lt;br /&gt;
&lt;br /&gt;The reason it prints out ten 9s in the first case is quite simple: the block that's created within the loop has a lifetime that's tied to the loop's inner scope. The block is destroyed at the next iteration of the loop, and when leaving the loop. Of course, "destroy" just means that its slot on the stack is available to be overwritten. It just happens that the compiler reuses the same slot each time through the loop, so in the end, the array is filled with identical pointers, and thus you get identical behavior.
&lt;br /&gt;
&lt;br /&gt;Do not read about how closures behave in other languages and assume that it carries over to Objective-C. Most other languages close over locals as a mutable reference rather than a const copy by default. The only exception to this that I'm aware of is Java, and it requires you to explicitly declare locals as &lt;code&gt;final&lt;/code&gt; (equivalent to &lt;code&gt;const&lt;/code&gt;) when closing over them. As far as I'm aware, no other language has Objective-C's behavior of closing over any local or parameter as a const copy, and of allowing explicitly-qualified locals to be closed mutably.</description><guid isPermaLink="true">2dce7100064b572af043f29340818c01</guid><pubDate>Mon, 25 Jan 2010 01:45:47 GMT</pubDate></item><item><title>Jason - 2010-01-24 23:17:30</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>Mike, you said:
&lt;br /&gt;
&lt;br /&gt;"void (^block[10])();
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int i = -1;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while(++i &amp;lt; 10)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block[i] = ^{ printf("%d\n", i); };
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for(i = 0; i &amp;lt; 10; i++)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block[i]();
&lt;br /&gt;
&lt;br /&gt;On my computer, this prints out ten 9s. If you copy the block when assigning, it prints out the correct 0-9 sequence. "
&lt;br /&gt;
&lt;br /&gt;This has more to do with the closure of the 'i' variable than the assignment to block. In C#, the compiler warns against this ("Access to modified closure" - Eric Lippert and Raymond Chen have excellent blog posts about this subject. Try assigning 'i' to a temporary variable so the block grabs a "local copy" of it:
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int i = -1;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while(++i &amp;lt; 10) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int icopy = i;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block[i] = ^{ printf("%d\n", icopy); };
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for(i = 0; i &amp;lt; 10; i++)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block[i]();
&lt;br /&gt;</description><guid isPermaLink="true">39138e737016738ac3ac3e477b841756</guid><pubDate>Sun, 24 Jan 2010 23:17:30 GMT</pubDate></item><item><title>mikeash - 2010-01-22 20:52:30</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>I've fixed the example. However, I would be extremely wary of writing code without the braces even so. It's bad to write code that will suddenly break mysteriously if you add some braces to a control structure, and it can also give you a bad habit since otherwise identical code with a for or while loop &lt;i&gt;does&lt;/i&gt; get an implicit inner scope and will break.</description><guid isPermaLink="true">d12b0b9bf452e42ae744915e0476b024</guid><pubDate>Fri, 22 Jan 2010 20:52:30 GMT</pubDate></item><item><title>Uli Kusterer - 2010-01-22 11:52:49</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>I don't understand the
&lt;br /&gt;
&lt;br /&gt;&lt;code&gt;
&lt;br /&gt;if( x )
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block = ...
&lt;br /&gt;else
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block = ...
&lt;br /&gt;block();
&lt;br /&gt;&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;example. That's all the same scope, why is this suddenly a problem with blocks? Did you forget the scope brackets on the "if"s here, to make it like Joachim Bengtsson's example? If you did, could you please fix the articles before everyone googling for blocks on the net learns it wrong?
&lt;br /&gt;
&lt;br /&gt;If not, could you elaborate on the differences in this regard between blocks and regular code?</description><guid isPermaLink="true">6fe917ea1b3705d20fb9091f35339f67</guid><pubDate>Fri, 22 Jan 2010 11:52:49 GMT</pubDate></item><item><title>mikeash - 2010-01-19 01:35:37</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>I don't think that your retain workarounds are practical. The problem is that in Objective-C/Cocoa as it stands now, you're allowed to retain any object at any time (as long as you balance it with a release later, of course). Your proposals, even the "error if retain count is non-zero when you return" one, would alter this. As a consequence, you either would be unable to pass stack objects to code you didn't control, like Cocoa APIs, or every API would need to be annotated to describe whether it's safe to pass a stack object to it or not.
&lt;br /&gt;
&lt;br /&gt;I think the retain_or_copy idea would be the way to go. This is essentially how blocks work: copying a block that's already on the heap just retains it. Howeer, this would require a wholesale reworking of the framework.
&lt;br /&gt;
&lt;br /&gt;As far as RAII goes, I think you can get pretty much the same benefits using blocks now. Take the typical RAII example of managing a file handle:
&lt;br /&gt;
&lt;br /&gt;&lt;code&gt;    file logfile("logfile.txt");
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;logfile.write("some log");&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;Using blocks, you can write a method that takes a block and does the same stuff:
&lt;br /&gt;
&lt;br /&gt;&lt;code&gt;    + (void)useFile: (NSString *)path withBlock: (void (^)(File *))block
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;File *file = [[self alloc] initWithFile: path];
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@try {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block(file);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@finally {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[file close];
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[file release];
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// to use it
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[File useFile: @"logfile.txt" withBlock: ^(File *file) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[file write: @"some log"];
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}];
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;This is how Ruby does it, for example.
&lt;br /&gt;
&lt;br /&gt;I really dislike C++ so I'm probably biased, but I think that closure-based resource management like this is actually better than C++-style RAII. RAII basically takes advantage of one aspect of the language (stack object memory management) to implement a completely unrelated feature (releasing resources when leaving a scope). The whole idea of closures is to be able to pass bits of code around like this, so it fits much better.
&lt;br /&gt;
&lt;br /&gt;Your mileage, of course, may vary.</description><guid isPermaLink="true">26976b87de2a5e67e3eadfe20065b82d</guid><pubDate>Tue, 19 Jan 2010 01:35:37 GMT</pubDate></item><item><title>J Osborne - 2010-01-19 01:00:05</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>&lt;div class="blogcommentquote"&gt;&lt;div class="blogcommentquoteinner"&gt; If Objective-C had stack objects, what would happen if you passed it to some other code which then tried to keep it around by retaining it? There's no way to prevent the object from being destroyed when the function which created it returns, so the retain can't work. The code which tries to keep the object around will fail, end up with a dangling reference, and will crash.
&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;Well you could define your way around it.   Cause an error when a stack object is retain'ed, but that isn't very useful.   You could allow the retain, but cause an error if the retain count is non-zero when the function that created the stack object returns.  That would be mostly workable.
&lt;br /&gt;
&lt;br /&gt;It would fail when you make changes to an existing framework that change an existing code path to one that "retains longer".   Then you would need to invent a retain_or_copy method that retains heap objects but does a copy for a stack object.
&lt;br /&gt;
&lt;br /&gt;That still fails if you want to support init methods that return new objects.
&lt;br /&gt;
&lt;br /&gt;You could allow stack based declaration of an object, but only pointer based calls, which would encourage "proper" use
&lt;br /&gt;
&lt;br /&gt;Object stackObj;
&lt;br /&gt;Object *sameObj = [&amp;amp;stackObj init];
&lt;br /&gt;
&lt;br /&gt;However people could (incorrectly) call things other then init using the address operator.    Maybe if you added a warning when the method doesn't start with init...
&lt;br /&gt;
&lt;br /&gt;Which is a lot of work...work that _does_ get you a good hook into "this method is called as the enclosing function exits" which is nice to use for resource acquisition (say locks, or many other things).    RAII is one of the few C++ things I &lt;b&gt;really&lt;/b&gt; miss in ObjC...
&lt;br /&gt;</description><guid isPermaLink="true">aa169128355353fa8ced10cdfbe5229a</guid><pubDate>Tue, 19 Jan 2010 01:00:05 GMT</pubDate></item><item><title>mikeash - 2010-01-16 21:56:20</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>Essentially correct. Technically, something like &lt;code&gt;NSArray array&lt;/code&gt; can live on the heap too, like if it's an instance variable of an object, but then it's just a part of a larger allocation and this has all of the same problems as stack objects do.</description><guid isPermaLink="true">87bdc5c824604a013dc4d2ac9a6a9a36</guid><pubDate>Sat, 16 Jan 2010 21:56:20 GMT</pubDate></item><item><title>Jason Bogdan - 2010-01-16 20:58:50</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>So the reason you *must* keep pointers to Objective-C objects is because they are allocated on the heap, and you can't have static, non-pointer variables (e.g. NSArray array) to objects on the heap?</description><guid isPermaLink="true">b455bf43a3a60c6b7eb9e44232056894</guid><pubDate>Sat, 16 Jan 2010 20:58:50 GMT</pubDate></item><item><title>mikeash - 2010-01-16 15:01:55</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>And thus I discover that my comment escaping code didn't handle tabs very well. It's better now. (Still not great: it unconditionally expands them to four spaces no matter where they are, but better.)</description><guid isPermaLink="true">8a07ce338ef1d00866d3450ad48e9b31</guid><pubDate>Sat, 16 Jan 2010 15:01:55 GMT</pubDate></item><item><title>Joachim Bengtsson - 2010-01-16 14:10:27</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>This is how I illustrate the problem with incorrect memory management with stack allocated block objects in my guide (&lt;a href="http://thirdcog.eu/pwcblocks/#cblocks-memory"&gt;http://thirdcog.eu/pwcblocks/#cblocks-memory&lt;/a&gt;):
&lt;br /&gt;&lt;code&gt;// Incorrect:
&lt;br /&gt;typedef void(^BasicBlock)(void);
&lt;br /&gt;void someFunction() {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;BasicBlock block;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(condition) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block = ^ { ... };
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} else {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block = ^ { ... };
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...
&lt;br /&gt;}
&lt;br /&gt;
&lt;br /&gt;// Basically equivalent of:
&lt;br /&gt;void someFunction() {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;BasicBlock block;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(condition) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;struct Block_literal_1 blockStorage = ...;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block = &amp;amp;blockStorage;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} // blockStorage falls off the stack here
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else 
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;struct Block_literal_1 blockStorage = ...;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block = &amp;amp;blockStorage;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} // blockStorage falls off the stack here
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// and block thus points to "non-existing"/invalid memory
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...
&lt;br /&gt;}
&lt;br /&gt;
&lt;br /&gt;// Correct:
&lt;br /&gt;void someFunction() {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;BasicBlock block;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(condition) {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block = Block_copy(^ { ... });
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} else {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block = Block_copy(^ { ... });
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...
&lt;br /&gt;}&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;The realization of how block memory management works came to me when reading Clang's implementation specification for blocks (&lt;a href="http://clang.llvm.org/docs/BlockImplementation.txt"&gt;http://clang.llvm.org/docs/BlockImplementation.txt&lt;/a&gt;); I had such a hard time understanding the problem before then.
&lt;br /&gt;
&lt;br /&gt;Jordy: Didn't know about if-without-brackets not creating scopes, thanks!</description><guid isPermaLink="true">32f446df5ee66651e49b23b28ac0aa5f</guid><pubDate>Sat, 16 Jan 2010 14:10:27 GMT</pubDate></item><item><title>Jens Ayton - 2010-01-16 11:30:10</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>Chris Ryland: in many languages, e.g. JavaScript, that would indeed be the problem. In C-with-blocks, it isn’t; because i isn’t __block-qualified, it’s a constant copy rather than a capture. Each time the block is set up, the value of i is copied into space in the on-stack block structure.
&lt;br /&gt;
&lt;br /&gt;However, because of the scoping issue, the same piece of stack is used each time, so each iteration effectively overwrites the previous iteration’s block object. The only difference is the value of i.
&lt;br /&gt;
&lt;br /&gt;This also explains why copying the block fixes the problem, which it wouldn’t in JS if there was such a thing as copying a closure there.</description><guid isPermaLink="true">8429b543642c61eb602ce9d68c7aaeb5</guid><pubDate>Sat, 16 Jan 2010 11:30:10 GMT</pubDate></item><item><title>Chris Ryland - 2010-01-16 05:14:10</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>(Sorry, our comments are crossing real-time.)
&lt;br /&gt;
&lt;br /&gt;I don't think that code illustrates a problem with block scope per se, but with the free variable access.
&lt;br /&gt;
&lt;br /&gt;The block copy captures the free variable (i) in that case.</description><guid isPermaLink="true">4cf890338c0d6c3eee060341182d30e1</guid><pubDate>Sat, 16 Jan 2010 05:14:10 GMT</pubDate></item><item><title>Chris Ryland - 2010-01-16 05:12:26</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>Can you expand a little on why that "if (x) ..." example is wrong?
&lt;br /&gt;
&lt;br /&gt;Those blocks' enclosing scope would be a function body, no? So they'd still be in scope at the call to block()?</description><guid isPermaLink="true">410d17ffc2e65cbc4729f33317cc16e9</guid><pubDate>Sat, 16 Jan 2010 05:12:26 GMT</pubDate></item><item><title>mikeash - 2010-01-16 00:03:24</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>It looks like the truth is somewhere in between. You appear to be right about if statements, but loops always create a scope. This code illustrates the problem:
&lt;br /&gt;
&lt;br /&gt;&lt;code&gt;    void (^block[10])();
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int i = -1;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while(++i &amp;lt; 10)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block[i] = ^{ printf("%d\n", i); };
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for(i = 0; i &amp;lt; 10; i++)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block[i]();&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;On my computer, this prints out ten 9s. If you copy the block when assigning, it prints out the correct 0-9 sequence.
&lt;br /&gt;
&lt;br /&gt;I could not make it happen with if statements, though, so it would seem that those are safe, at least.</description><guid isPermaLink="true">a1cb55d285a44c76848dae46b2cbac19</guid><pubDate>Sat, 16 Jan 2010 00:03:24 GMT</pubDate></item><item><title>Jordy/Jediknil - 2010-01-15 23:48:35</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>As I understand it, a new scope is only created in C when you use &lt;code&gt;{ }&lt;/code&gt;, and not just arbitrary if/else or (do/)while statements. After all, the body of an if statement in C is a &lt;i&gt;single&lt;/i&gt; statement. So the example should probably have braces to be correct.
&lt;br /&gt;
&lt;br /&gt;That said, both GCC and Clang appear to be forgiving here, even with the braces. That doesn't make it correct, though.</description><guid isPermaLink="true">b1ef40f4a1ca46f20ab929ab05892bc5</guid><pubDate>Fri, 15 Jan 2010 23:48:35 GMT</pubDate></item><item><title>mikeash - 2010-01-15 23:00:54</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>Thanks for that, I've fixed it.</description><guid isPermaLink="true">6aae8549282bb6485b68cce78584390f</guid><pubDate>Fri, 15 Jan 2010 23:00:54 GMT</pubDate></item><item><title>Psy| - 2010-01-15 22:37:09</title><link>http://www.mikeash.com/?page=pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html#comments</link><description>I think there is a mistake in here, at the end it's "stack":
&lt;br /&gt;"A stack object is just an object where the memory for that object is allocated on the heap."
&lt;br /&gt;
&lt;br /&gt;Otherwise great subject. :P</description><guid isPermaLink="true">54700e1dc5e68953120477ca21fff295</guid><pubDate>Fri, 15 Jan 2010 22:37:09 GMT</pubDate></item></channel></rss>
