Aside from the closure structure, there's a second structure for __block variables (which are shared and mutable). There may also code generated for calling c++ copy constructors/destructors and Objective C retain/release-ing.

Blocks are never magically moved from the stack to the heap. There are two runtime function calls -- Block_copy(block) and Block_destroy(block) -- for managing block lifetime. (Objective C people can use [block copy] / [block release]).

If the block is stored on the stack, Block_copy will copy it to the heap (and return a pointer to the new heap block). Otherwise, it just increments a reference counter.

If you pass your block to a function that keeps it around for later, then it will get copied to the heap (if necessary). C is not doing anything behind your back, though.