Karolis
Karolis

Reputation: 887

Simplify block reference declaration using typedefs

I'm working through Advanced Mac OS X Programming book and one exercise has me stumbled.

Use typedefs to simplify the following block reference declaration:

int (^(*(^get_block_factory_funcptr)(void))(int))(void);

Here's how I understand the declaration:

Function not taking arguments, returns a block which returns a void pointer, which is a pointer to a function that takes int for an argument and returns a block which has no arguments, returns an int.

Now given that, I have these 2 typedefs

typedef void *(^get_block_factory_funcptr)(void);
typedef int (^myBlock(int))(void);

However I have no idea how to combine them to a single declaration, any help appreciated

Upvotes: 1

Views: 52

Answers (1)

Darren
Darren

Reputation: 25619

If I'm reading it correctly, it's a block that returns a function pointer that returns a block. The name is a hint.

One way to figure it out is to start with the end result and work backwards. Or, start from the inside and work outwards.

What is get_block_factory_funcptr? It's a block:

MyBlock get_block_factory_funcptr;

What does it do? It takes a void and it returns a "Block Factory" function pointer. Let's declare MyBlock:

typedef FactoryFuncPtr (^MyBlock)(void);

What is FactoryFuncPtr? It takes an int and returns another block:

typedef OuterBlock (*FactoryFuncPtr)(int);

What is OuterBlock? It takes a void and returns an int:

typedef int (^OuterBlock)(void);

Those are the declarations in reverse order.

Edit: A working example.

#import <Foundation/Foundation.h>

typedef int (^OuterBlock)(void);
typedef OuterBlock (*FactoryFuncPtr)(int);
typedef FactoryFuncPtr (^MyBlock)(void);

OuterBlock factory(int foo) {
    return ^ {
        printf("A block with %d\n", foo);
        return 123;
    };
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        int (^(*(^get_block_factory_funcptr)(void))(int))(void) = ^ {
            return &factory;
        };

        MyBlock myBlock = get_block_factory_funcptr;
        FactoryFuncPtr foo = myBlock();
        OuterBlock bar = foo(999);
        int baz = bar();
        printf("Final %d\n", baz);
    }
    return 0;
}

Upvotes: 2

Related Questions