Re: NSValue valueWithBytes:objCType:
On 25.08.2013, at 19:50, Stephen J. Butler stephen.but...@gmail.com wrote: My guess, and this is only a guess, is that NSValue only uses the type property to make sure two NSValues have the same layout before calling memcmp (or such) on them. We have a lot of evidence that it doesn't do a deep inspection of the type in order to give a more accurate comparison. Can you not bzero() the structs before writing to them and placing them in NSValues? That would solve your problem. That's not a general solution. Consider: // Some Library: struct s_t { … }; s_t foo(); s_t bar(); // Apple's library: // macro: #define StructsAreEqual(a, b) \ … // uses NSValue's method isEqualToValue: // My code: assert( StructsAreEqual(foo(), bar()) ); My point is, the macro StructsAreEqual is not reliable. Andreas ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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 arch...@mail-archive.com
Re: NSValue valueWithBytes:objCType:
On Mon, Aug 26, 2013, at 12:39 AM, Andreas Grosam wrote: My point is, the macro StructsAreEqual is not reliable. Then don't do that. And file a bug about the framework that does. In the meantime, try to work around it. --Kyle Sluder ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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 arch...@mail-archive.com
Re: NSValue valueWithBytes:objCType:
On Aug 24, 2013, at 22:09 , Andreas Grosam agro...@onlinehome.de wrote: 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). I have to admit I have a hard time fathoming the purpose of NSValue, and personally I’ve only every used it “in anger” once. As far as I can tell, it is a backstop when you need to store some random C type in an NSArray and do not need semantics, but do want to keep track of the actual type. I use it when my bridge code punts: I can’t use the value on the “scripting” side of the bridge, but I can replay it successfully if it’s needed in another call. If you need semantics, do not use NSValue, use an actual Objective-C class, either by re-creating that struct as an object or wrapping it explicitly. Cheers, Marcel ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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 arch...@mail-archive.com
Re: NSValue valueWithBytes:objCType:
On 24.08.2013, at 23:01, Jean-Daniel Dupas devli...@shadowlab.org wrote: Le 24 août 2013 à 22:09, Andreas Grosam agro...@onlinehome.de a écrit : That's not a problem specifics to NSValue. I disagree. Please read the documentation of NSValue: valueWithBytes:objCType: Creates and returns an NSValue object that contains a given value, which is interpreted as being of a given Objective-C type. isEqualToValue: Returns a Boolean value that indicates whether the receiver and another value are equal. The fact is, the result of isEqualToValue: is more often undefined, implementation defined or completely random when applied to structs. You should know what you do when manipulating structs. I think, I do - otherwise, I wouldn't come up with this problem. The problem is, that in some library which we cannot mention here, two encoded structs wrapped into NSValues together with method isEqualToValue: will be used as a means to compare structs. IMO, this's not a reliable approach. Andreas ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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 arch...@mail-archive.com
Re: NSValue valueWithBytes:objCType:
My guess, and this is only a guess, is that NSValue only uses the type property to make sure two NSValues have the same layout before calling memcmp (or such) on them. We have a lot of evidence that it doesn't do a deep inspection of the type in order to give a more accurate comparison. Can you not bzero() the structs before writing to them and placing them in NSValues? That would solve your problem. On Sun, Aug 25, 2013 at 12:34 PM, Andreas Grosam agro...@onlinehome.dewrote: On 24.08.2013, at 23:01, Jean-Daniel Dupas devli...@shadowlab.org wrote: Le 24 août 2013 à 22:09, Andreas Grosam agro...@onlinehome.de a écrit : That's not a problem specifics to NSValue. I disagree. Please read the documentation of NSValue: valueWithBytes:objCType: Creates and returns an NSValue object that contains a given value, which is interpreted as being of a given Objective-C type. isEqualToValue: Returns a Boolean value that indicates whether the receiver and another value are equal. The fact is, the result of isEqualToValue: is more often undefined, implementation defined or completely random when applied to structs. You should know what you do when manipulating structs. I think, I do - otherwise, I wouldn't come up with this problem. The problem is, that in some library which we cannot mention here, two encoded structs wrapped into NSValues together with method isEqualToValue: will be used as a means to compare structs. IMO, this's not a reliable approach. Andreas ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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/stephen.butler%40gmail.com This email sent to stephen.but...@gmail.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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 arch...@mail-archive.com
NSValue valueWithBytes:objCType:
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 ;) 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*. Andreas ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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 arch...@mail-archive.com
Re: NSValue valueWithBytes:objCType:
Le 24 août 2013 à 22:09, Andreas Grosam agro...@onlinehome.de 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 (Cocoa-dev@lists.apple.com) 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 arch...@mail-archive.com
Re: NSValue valueWithBytes:objCType:
Would defining the structs as packed make a difference for the comparisson? Sandor Szatmari On Aug 24, 2013, at 17:01, Jean-Daniel Dupas devli...@shadowlab.org wrote: Le 24 août 2013 à 22:09, Andreas Grosam agro...@onlinehome.de 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 (Cocoa-dev@lists.apple.com) 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/admin.szatmari.net%40gmail.com This email sent to admin.szatmari@gmail.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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 arch...@mail-archive.com