Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested block programming

According to this block programming tutorial:

http://thirdcog.eu/pwcblocks/

The following nested block:

void (^(^myblockptr)(void (^)()))();

Is a pointer to a block returning a block taking a block

It says that it is equivalent to:

typedef void (^Block)();
Block (^myblockptr)(Block);

I guess that (void (^)()) corresponds to the parameters, i.e, (Block). However, I am unable to see which part of the nested expression corresponds to the returned block.

Are you able to identify the returned block in the nested expression?

like image 349
Freeman Avatar asked Jul 09 '26 01:07

Freeman


2 Answers

As Joshua’s said, when analysing C declarations it’s a good idea to start from the inside out.

void (^(^myblockptr)(void (^)()))();

Since myblockptr is the variable, let’s split the declaration in two parts, to the left of the variable and to the right of the variable:

void (^(^myblockptr)    (void (^)()))();

We know that (^myblockptr) is a block because of ^, so to its left we should find its return type, and to its right we should find its parameter types.

Let’s analyse the parameters that myblockptr takes, moving to the right. They should be grouped by parentheses right after the (^myblockptr):

void (^(^myblockptr)    (void (^)())    )();

It’s a single parameter, which is a block because of ^:

void (^)()

and now it’s easy to see that the parameter is a block that returns void and takes no parameters.

Moving farther to the right, there’s a closing parenthesis so we need to analyse the leftmost part:

void (^    (^myblockptr)…

where we see that myblockptr returns a block that returns void. Since it returns a block, we should find the parameter types accepted by the returned block after the closing parenthesis that matches the leftmost opening paranthesis:

void (^    (^myblockptr)(void (^)())    )();

since it’s (), we see that the returned block doesn’t have any parameters.

enter image description here

In summary: myblockptr is a block that (to the right) accepts a parameter that is a block that takes no parameters and returns void and (to the left) returns a block that takes no parameters and returns void. Since the return type of myblockptr and the (single) parameter type are the same:

typedef void (^Block)();

leading to:

Block (^myblockptr)(Block);

You may want to read Steve’s Reading C type declarations and, as mentioned by Jeremy, Fish’s cdecl.org.

You should read the block definition from the inside out.

Lets break it down.

void (^(^myblockptr)(void (^)()))();

void (^)() declares a block which is a parameter

RETURNTYPE (^myblockptr)(PARAMS) declares a block named myblockptr with params

and the external void (^(....)()) refers to the return type from the block.

Putting it all together gets you the original declaration.

like image 44
Joshua Weinberg Avatar answered Jul 10 '26 13:07

Joshua Weinberg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!