gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFA]: BOOL coding standards (Was: Problemwith+numberWithBool:?)


From: David Ayers
Subject: Re: [RFA]: BOOL coding standards (Was: Problemwith+numberWithBool:?)
Date: Sun, 08 Feb 2004 00:02:34 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040113

Kazunobu Kuriyama wrote:

David Ayers 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.


I'm afraid this is nothing to do with C truth values. Before (i=256) is passed to -numberWithBool, it has been evaluated as 0 by a compiler (if a two's complement representation is used for that value). This is because you assigned an int value to a BOOL (=unsigned char) one. Believe or not, according to K&R A6.2,

i=256 is an assignment, yet it evaluates to the value of the assignment. The compiler converts the integer to an unsigned char which is in this case 0 as you describe below.


(quote)
Any integer is converted to a given unsigned type by finding the smallest non-negative value that is congruent to that integer, modulo one more than the largest value that can be represented in the unsigned type. In a two's complement representation, this is equivalent to left-truncation if the bit pattern of the unsigned type is narrower, and to zero-filling unsigned values and sign-extending
signed values if the unsigned type is wider.

When any integer is converted to a signed type, the value is unchanged if it can be represented in
the new type and is implementation-defined otherwise.
(unquote)

Consequently, the compiler faithfully generated the code reflecting what you wrote.

I don't think we are in disagreement.  My point is, in C truth semantics:

int i = 256;
if (i)

will be evaluted as true.  But

if ([[NSNumber numberWithBool: i] boolValue])

will return the 'NO' BOOL instance and be evaluated as false.

You can't rely on the C truth value (i.e. rely on the "true" value or 256) to be passed through the method invocation which converts the integer to unsgnied char in this case '0' and expect to have get the 'YES' BOOL value as the parameter in the implementation of +numberWithBool.

IOW: C "truths" (i.e. C truth semantice) aren't implicitly converted to BOOL YES/NO. The conversion must be made explict.

Cheers,
David






reply via email to

[Prev in Thread] Current Thread [Next in Thread]