Re: NSValue valueWithBytes:objCType:

2013-08-26 Thread Andreas Grosam

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:

2013-08-26 Thread Kyle Sluder
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:

2013-08-25 Thread Marcel Weiher

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:

2013-08-25 Thread Andreas Grosam

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:

2013-08-25 Thread Stephen J. Butler
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:

2013-08-24 Thread Andreas Grosam
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:

2013-08-24 Thread Jean-Daniel Dupas

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:

2013-08-24 Thread Sandor Szatmari
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