Re: Crash when calling va_arg()
Re: Crash when calling va_arg()
- Subject: Re: Crash when calling va_arg()
- From: email@hidden
- Date: Wed, 04 Jul 2012 18:09:55 -0700
I prefer the NULL sentinel too. You might like to check if
__attribute__((sentinel(0,1))) added to your function header gets the
compiler to warn you if you forget it, very useful that.
> Hi Fritz and Jens,
>
> It makes total sense now. Out of the two options (NULL sentinel vs a
> number to indicate the number of args), I would choose NULL because out of
> the two, it's more foolproof. Is there a consensus about which option is
> considered best practice?
>
> Thanks again,
>
> -- Tito
>
> On Jul 4, 2012, at 4:43 PM, Fritz Anderson <email@hidden>
> wrote:
>
>> On 4 Jul 2012, at 6:30 PM, Tito Ciuro wrote:
>>
>>> 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?
>>
>> Not possible.
>>
>> Notionally, all parameters are passed to C functions in memory on a
>> stack, which is unformatted and could contain anything. A function has
>> no way of knowing how many parameters have been pushed onto the stack,
>> or where the memory trails off into saved processor state and the like,
>> or the types, or the amounts of memory they subtendâ¦.
>>
>> Most variadic functions require sentinels (usually NULL) to tell them to
>> stop looking for parameters. The best-known exceptions are
>> printf()-family functions, which know what to find on the stack because
>> the format string tells them.
>>
>> â F
>>
>> --
>> Fritz Anderson
>> Xcode 4 Unleashed: Don't bring your bathroom copy into the kitchen â
>> were you raised in a barn?
>> <http://x4u.manoverboard.org/>
>>
>>
>>
>
>
> _______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> 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:
>
> This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden