Hello,

I've hit a wall while experimenting with variadic functions and blocks. The 
code works pretty well until the second block is executed. After that, it 
crashes the next time va_arg() gets called. Here's the code:

#import <Foundation/Foundation.h>

typedef id (^fooBlock)(id result, NSError **error);
void blockStep(fooBlock firstBlock, ...);

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        
        blockStep (
                   ^ (id result, NSError **error) {
                       NSMutableString *value = [NSMutableString new];
                       [value appendString:@"One!"];
                       return value;
                   },
                   ^ (id result, NSError **error) {
                       NSMutableString *value = [NSMutableString new];
                       if (nil != result) {
                           [value appendString:result];
                           [value appendString:@", "];
                       }
                       [value appendString:@"Two!"];
                       return value;
                   }
        );
        
    }
    return 0;
}

#pragma mark -

void blockStep(fooBlock firstBlock, ...)
{
    va_list args;
    va_start(args, firstBlock);
    id result = nil;
    
    do {
        result = firstBlock(result, nil);
        NSLog(@"%@", result);
    } while (nil != (firstBlock = va_arg(args, fooBlock)));
    
    va_end(args);
}

The output looks like this:

> 2012-07-04 16:18:40.000 BlockStep[12418:303] One!
> 2012-07-04 16:18:56.533 BlockStep[12418:303] One!, Two!

I've eliminated the crash by adding a nil sentinel in blockStep():

        blockStep (
                   ^ (id result, NSError **error) {
                       NSMutableString *value = [NSMutableString new];
                       [value appendString:@"One!"];
                       return value;
                   },
                   ^ (id result, NSError **error) {
                       NSMutableString *value = [NSMutableString new];
                       if (nil != result) {
                           [value appendString:result];
                           [value appendString:@", "];
                       }
                       [value appendString:@"Two!"];
                       return value;
                   },
                   nil
        );

This allows it to work without crashing, but I'd like if possible to avoid 
having to place the sentinel. Any ideas?

Thanks in advance,

-- Tito
_______________________________________________

Cocoa-dev mailing list ([email protected])

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to