Re: NSValue valueWithBytes:objCType:
Re: NSValue valueWithBytes:objCType:
- Subject: Re: NSValue valueWithBytes:objCType:
- From: Sandor Szatmari <email@hidden>
- Date: Sat, 24 Aug 2013 23:13:29 -0400
Would defining the structs as packed make a difference for the comparisson?
Sandor Szatmari
On Aug 24, 2013, at 17:01, Jean-Daniel Dupas <email@hidden> wrote:
>
> Le 24 août 2013 à 22:09, Andreas Grosam <email@hidden> a écrit :
>
>> What's the purpose of NSValue's class method
>>
>> + (NSValue *)valueWithBytes:(const void *)value objCType:(const char *)type; ?
>>
>> It seems, NSValue will simply memcpy the content of value, and "somehow" determine the size in bytes from the string given in type. Is that reliable at all? (I have major doubts).
>>
>>
>> It also seems, despite making the illusion having knowledge about the underlaying type, NSData fails to compare correctly two NSData objects which have been initialized by the same "Objective-C" type.
>>
>>
>> That is, this code is generally "unsafe":
>>
>> struct a_s {
>> unsigned char _b;
>> long _l;
>> };
>>
>> -(void) foo {
>> struct a_s;
>>
>> // suppose, we scramble some bits on the stack …
>>
>> a._b = 0;
>> a._l = 1;
>>
>> b._b = a._b;
>> b._l = a._l;
>>
>> NSValue *a_encoded = [NSValue valueWithBytes:&a objCType:@encode(struct a_s)];
>> NSValue *b_encoded = [NSValue valueWithBytes:&b objCType:@encode(struct a_s)];
>>
>> assert([a_encoded isEqualToValue: b_encoded]); // May fail!
>> }
>>
>>
>> The assert may fail, since apparently NSData simply performs a memcpy. This of course fails miserably if we intended to compare the _struct_ values.
>>
>> Nonetheless, NSData pretends to be able to return the correct result when comparing the encoded values. Well, of course this may be considered by NSData as correct - despite it's different to comparing the corresponding struct values - since only NSData knows and defines what makes a NSValue equal to another ;)
>
> When compiling a struct, the compiler add padding where needed so that each field is aligned as required by the ABI. The padding can contains any value and nothing force it to be initialized to 0.
> When you memcpy a struct, you include the padding, which can contains anything. When you restore the value, all field are restored properly though, but there is no guarantee that a memcmp of two struct with all field containing the same value will always returns the same result.
>
>> So again, I cannot see where this feature can be ever sensible, and does not simultaneously introduce more harm than use.
>>
>> Additionally, I'm worried about the fact, that a *particular Apple library* will use the above technique to *compare structs*.
>
>
> That's not a problem specifics to NSValue. You should know what you do when manipulating structs.
>
> -- Jean-Daniel
>
>
>
>
>
> _______________________________________________
>
> 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