On Mar 18, 2009, at 3:05 PM, James Maxwell wrote:

I've got a really frustrating, and really silly problem.

I have some fairly complex machine learning code I'm working on. I've noticed inconsistent output from a particular method. I'm doing some fairly nasty array and matrix stuff, which is all done in C, and I pass the arrays around wrapped in NSData objects. What's really strange is that, in this particular method, if I place an NSLog after calling and unwrapping a particular 2D matrix, then the output is as expected. If I remove the NSLog, the output is incorrect (or at least, unexpected). The system is pretty complex, and involves 4 different classes, so I won't post it here, and obviously I don't expect any magical help. But does anybody have any experience with something this flaky? Whereby literally adding a single NSLog (and thus obviously slowing things down a fair bit) makes the method run correctly?... It's just bizarre, to me.

Maybe somebody here has worked their way into a similar corner? Obviously I've done something stupid somewhere, but I don't really know how to go about finding it. It was weird enough to realize that the NSLog could make or break my output - tracking down the actual reason why is just baffling... Everything being done in these classes is basically procedural stuff, so it doesn't seem like timing should dramatically influence the output. But I am doing *lots* of iterations over this data. Does that suggest anything?

Any thoughts very much appreciated.

cheers,

J.

Hi James,

I once encountered a case that sounds similar. I had a method that returned a BOOL (signed char). I expected the return value to be false, but the calling method behaved as it had received true. When I added a debugging printf() inside the callee, the caller bizarrely started getting back false. A Heisenbug if there ever was one!

The problem turned out to be as follows: the caller did not have a declaration for the method it was calling. This causes the compiler to assume that the callee returned an id (much like implicit int in C), so it looked at all four bytes of the return register. But the callee returned just one byte, so it only bothered to set the least significant byte in the return register. Thus the caller ended up comparing NULL to whatever garbage happened to be in the remainder three bytes of %eax.

printf() returns an int containing the number of characters written. Since I was writing fewer than 256 characters, the upper three bytes of %eax were all 0 - it cleared exactly the portion that needed clearing. So it happened to work. But without the printf(), nothing cleared those bytes and I'd often get nonzero when I expected zero.

So make sure that every caller of your method has a declaration of that method in scope. If that's not it, hope you enjoyed the war story.

-Peter

_______________________________________________

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to