Matt Galloway

My home on the 'net.

Blocks in C++ classes - very broken

I was trying to use blocks (an Apple extension to the C language) in a C++ class when I came across a very strange problem. If you try to declare a block inside a C++ class member function that declares variables inside the block, then you end up with GCC (the one that comes with the Mac/iOS SDK) throwing an error.

For instance, consider this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class SomeClass {
public:
    SomeClass() {}
    ~SomeClass() {}

    void doSomething() {
        void (^block)(void) = ^{
            int a = 0;
        };
    }
};

int main (int argc, char * const argv[]) {
    return 0;
}

If you compile it, GCC will throw this error:

1
2
main.cpp: In function 'void __doSomething_block_invoke_1(void*)':
main.cpp:8: error: 'int SomeClass::a' is not a static member of 'class SomeClass'

Sadly there is no workaround that I can find as yet.

I have found a (not very nice) workaround:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class SomeClass {
public:
    SomeClass() {}
    ~SomeClass() {}

    void doSomething() {
        void (^block)(void) = ^{
            int ::a;
            a = 0;
        };
    }
};

int main (int argc, char * const argv[]) {
    return 0;
}

Note that you cannot initialise the variable at the same time as declaring it inside the block. You must declare it, forcing global scope and then initialise it.

Comments