|
From: | David Ayers |
Subject: | Re: [RFA]: BOOL coding standards (Was: Problemwith+numberWithBool:?) |
Date: | Sat, 07 Feb 2004 12:36:27 +0100 |
User-agent: | Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040113 |
Manuel Guesdon wrote:
Hi, On Sat, 07 Feb 2004 11:26:18 +0100 David Ayers <address@hidden> wrote:>| During private discussion with Richard, he pointed out to me why the >| result C tests *cannot* be safely interpreted as BOOL values. >| >| C tests evaluated by if/while/for take into account the full size of >| their arguments. Assigning a value of a type larger than char to a BOOL >| (or providing such a value as an argument to a method/function expecting >| a BOOL) ignores all higher ordered bytes. >| >| IOW>| [NSNumber numberWithBool: (i=256)]; => NO >| [NSNumber numberWithBool: (i=512)]; => NO >| [NSNumber numberWithBool: (i=768)]; => NO >| ...>| i.e. if the C truth value was 'short', we have 255 values that would >| potentially be false negatives, for 'int' it would already be 16.777.215 >| (2^(8*3)-1). >| >| Therefor:>| [NSNumber numberWithBool: isupper(someChar)];>| where isupper can be replaced with any other function returning an int, >| is unsafe.Right, I've thought about casting but not this point. I haven't tested but I think compiler will emit a warning in such a case.
Nope, at least not by default. And notice that casting (BOOL)(i=256) will still result in 0.
>| This clearly shows that my previous assumption that C truth values may >| be used for BOOL parameters is plainly false. So let my turn my view >| point by about 180 degrees :-/. >| >| - The only valid values for BOOL shall be YES and NO.OK >| - Any method/function returning BOOL *must* return YES or NO. OK.>| - There is no way that we can detect faulty conversions by the caller >| within the callee, therefor it's the callers responsibility to provide a >| true BOOL and he may *not* rely on C truth semantics.OK.>| - There is a technical reason for asserting that a BOOL must be YES or >| NO, as it helps uncover misbehaving callers.OK. >| Our example must be written as: >| [NSNumber numberWithBool: (isupper(someChar) != 0)]; OK.>| Therefore, I don't see any practical benefit in testing "!= NO" instead >| of "== YES" anymore. I'd even go so far as to say that using "!= NO" >| gives a false sense of robustness. >| >| I retract my offer (unposted patch) to use isYES() to test or implicitly >| BOOLify parameters or return values. >| >| I have no more objections on asserting YES/NO values for BOOL:s or >| warning about invalid values.Finally OK.>| I thought isYES() would be a good name for a '== YES' replacement. I >| don't think isYES() is a good name for general BOOL value >| assertion/warnings. >| >| I'd prefer something more explicit (but maybe too bulky) like >| GSCheckBOOL(), GSAssertBOOL() ...???Could you explain problems if using IsYes for assertion/warning ? I'm not sure we'll get quickly the reflex of adding GSCheckBOOL() :-)
I don't feel too strongly about it. If no one else sees an issue with it, I'm fine to stick with isYES(). I just imagined code that could would look like:
-(void)methodTakingBool:(BOOL)flag { if (isYES(flag) == NO) { ... if (isYES([obj isSomething]) == NO) /* Remember it's not just a replacement for == YES anymore, but a general BOOL assertion mechanism that can be used anywhere a developer sees fit. */ ... would be hard to parse. But I guess a better /style/ would be: -(void)methodTakingBool:(BOOL)flag { flag = isYES(flag); if (flag == NO) { ... ??? Cheers, David
[Prev in Thread] | Current Thread | [Next in Thread] |