Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid __block type specifier behavior #44

Closed
GunGraveKoga opened this issue Oct 12, 2016 · 5 comments
Closed

Invalid __block type specifier behavior #44

GunGraveKoga opened this issue Oct 12, 2016 · 5 comments
Labels

Comments

@GunGraveKoga
Copy link

On Windows and Mac OS X (and maybe Linux) __block variable behavior is not corresponding to Apple (and Clang) documentation.

Simple code tested on Mac OS:

#import <Foundation/Foundation.h>
#import <ObjFW/ObjFW.h>

typedef void(^block_t)(void);

block_t createBlock(void) {
    __block int i = 2;

    return [^{ NSLog(@"%i", i); i--; NSLog(@"%i", i);} copy];
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");

        block_t myBlock = createBlock();

        myBlock();
        myBlock();
    }
    return 0;
}

Linked with ObjFW framework (or dll on Windows):

2016-10-13 00:29:29.416 testclang[13106:4746764] Hello, World!
2016-10-13 00:29:29.417 testclang[13106:4746764] 5256272
2016-10-13 00:29:29.417 testclang[13106:4746764] 5256271
2016-10-13 00:29:29.417 testclang[13106:4746764] 5256272
2016-10-13 00:29:29.417 testclang[13106:4746764] 5256271
Program ended with exit code: 0

Linked only with Foundation:

2016-10-13 00:30:56.425 testclang[13119:4747431] Hello, World!
2016-10-13 00:30:56.426 testclang[13119:4747431] 2
2016-10-13 00:30:56.426 testclang[13119:4747431] 1
2016-10-13 00:30:56.426 testclang[13119:4747431] 1
2016-10-13 00:30:56.426 testclang[13119:4747431] 0
Program ended with exit code: 0

As You can see, in ObjFW case, variable "i" captured by "myBlock" is dead after stack destruction of function "block_t createBlock(void)"

@Midar
Copy link
Collaborator

Midar commented Oct 15, 2016

Oh wow, this is bad. And while there is a test for __block, it is not thorough enough to catch this. Let me debug this and improve on the test.

@Midar
Copy link
Collaborator

Midar commented Oct 15, 2016

Fixed.

@Midar Midar closed this as completed Oct 15, 2016
@Midar Midar added the bug label Oct 15, 2016
@GunGraveKoga
Copy link
Author

One more problem I found.
Two different blocks, that's capture single __block variable, does not share value of that variable.
We have variable __block int i = 2;
If first block do some thing like this i--;
In the second block variable "i" is still equal 2

@Midar
Copy link
Collaborator

Midar commented Oct 17, 2016

I cannot reproduce this. Can you check your on the latest version? There were two commits to fix this, maybe you only checked out the first?

The following code works for me:

#import <ObjFW/ObjFW.h>

typedef void (^voidblock)(void);

static OFArray*
test()
{
    __block double d = 0;
    voidblock block1 = Block_copy(^ {
        d++;
    });
    voidblock block2 = Block_copy(^ {
        of_log(@"%f", d);
    });
    return @[block1, block2];
}

int
main()
{
    OFArray <voidblock> *t = test();

    t[0]();
    t[1]();

    return 0;
}

@GunGraveKoga
Copy link
Author

Yes, it's work for now.
Tested build with latest changes.
Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants