Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blocks and stack

I know that blocks are created in the stack. However, since I don't have enough knowledge about stack and local variables, I can not understand why I should move the block to heap in order to have expected result. Intuitively I feel like the block code chunk has only 1 instance in the stack, this code is referencing to local variable i 3 times. If I copy it to heap it will have 3 different instances and each time it will capture 3 different values of i during copy procedure. But I would really like to know more about block code in stack, heap and referencing local variables.

for (int i=0; i<3; i++)
    b[i] = ^{ return i;};
for (int i=0; i<3; i++)
    printf("b %d\n", b[i]());
like image 241
Pablo Avatar asked May 27 '11 04:05

Pablo


People also ask

What is a block stack?

Block stacking is a form of palletised storage that does not require any type of storage equipment, and instead loaded pallets are placed directly on the floor and built up in stacks to a maximum stable storage height.

Why are blocks good for stacking?

Stacking blocks is not only beneficial because it develops hand-eye coordination or social skills, but it is also beneficial because during block stacking toddlers begin to think like mathematicians. Specifically, they learn the most basic concepts in geometry.

At what age do babies play with blocks?

10-12 Months: This is the age when baby can start stacking blocks. Baby may be able to stack 2 blocks on purpose. Baby can grasp and manipulate blocks of different sizes.

What age do you stack 4 blocks?

Stacks Four Blocks Development Milestone emerges from age 18 to 22 months. At this stage your child can successfully stack four blocks without them toppling over.


1 Answers

Scopes, man. Scopes.

Rewrite that as:

void georgeClinton() {
    int (^b[3])(); // iirc
    // georgeClinton's scope
    for (int i=0; i<3; i++) {
        // for's scope
        b[i] = ^{ return i;};
    }
}

On every pass through that for() loop, for's scope is effectively a new scope. But, of course, scopes are on the stack.

When you call georgeClinton(), you effectively push georgeClinton()'s scope onto the stack. And when georgeClinton() returns with some funky goodness, georgeClinton()'s scope is popped off the stack, leaving the stack in whatever state it was in when the push happened (with a potential modification for the return value).

A for() loop is the same thing; each iteration pushes state onto the stack and pops it off at the end of the iteration.

Thus, if you store anything on the stack in an iteration of a for() loop, like a block, that thing will be destroyed at the end of the iteration. To preserve it, you must move it to the heap (where you control the lifespan of the state of any given allocation).

The key being that a block typed variable is really a pointer; it is a reference to a structure that defines the block. They start on the stack for efficiency and this can lead to subtle issues like this one.

Note that a block is really two things; it is a reference to the bit of immutable code that implements the block (which is really just like a function pointer) and it is a description of the data captured in the block and how that data is to be moved to the heap when copied.

That is, a block is the combination of data and code. Code that never changes. Data that is captured as the execution pointer passes over the expression that defines the block (i.e. the block "closes over" the current state of execution).

It is that latter bit that trips you up; when a block is created on the stack, it is created with slots to hold captured data, also on the stack.

like image 147
bbum Avatar answered Oct 05 '22 23:10

bbum