In one of Apple's header files for libdispatch
, queue.h
, the following warning appears:
// The declaration of a block allocates storage on the stack.
// Therefore, this is an invalid construct:
dispatch_block_t block;
if (x) {
block = ^{ printf("true\n"); };
} else {
block = ^{ printf("false\n"); };
}
block(); // unsafe!!!
// What is happening behind the scenes:
if (x) {
struct Block __tmp_1 = ...; // setup details
block = &__tmp_1;
} else {
struct Block __tmp_2 = ...; // setup details
block = &__tmp_2;
}
// As the example demonstrates, the address of a stack variable is
// escaping the scope in which it is allocated. That is a classic C bug.
Try as I may, I cannot come up with a test case that exemplifies this bug. I can create blocks that are instantiated on the stack, but they (seem to) always appear at unique addresses on the stack, even when out of scope with respect to each other.
I imagine that the answer to this is simple, but it escapes me. Can anyone fill the gaps in my (limited) understanding?
EDIT: I've seen this response, but I don't quite understand how that instance can translate to my example posted above. Can someone show me an example using if
constructs?