Reputation: 5374
I came across a weird issue when testing my opensource project MHTextSearch. At line 169 of MHTextIndex.m:
uint64_t maxLength = [indexedString maximumLengthOfBytesUsingEncoding:encoding];
// some code
for (...) {
[indexedString getBytes:keyPtr
maxLength:maxLength
usedLength:&usedLength
encoding:encoding
options:NSStringEncodingConversionAllowLossy
range:subRange
remainingRange:NULL];
// some more code
}
Nothing, anywhere else, modifies maxLength
. On the second iteration, maxLength is equal to 0
, no matter what its previous value was. If I set a watchpoint on it, I see it changes in -[NSString getBytes:maxLength:usedLength:encoding:options:range:remainingRange:]
, at
0x100038d19: movq -0x30(%rbp), %rdx
0x100038d1d: movq %rdx, (%rsi)
0x100038d20: testq %rcx, %rcx << this instruction
The very weird thing about this is that it only happens on the x86_64 architecture, and it can be fixed if I change the code like this
uint64_t maxLength = [indexedString maximumLengthOfBytesUsingEncoding:encoding];
uint64_t strLength = maxLength;
// some code
for (...) {
[indexedString getBytes:keyPtr
maxLength:strLength
usedLength:&usedLength
encoding:encoding
options:NSStringEncodingConversionAllowLossy
range:subRange
remainingRange:NULL];
// some more code
}
With this code, maxLength
still gets changed to 0 at the same instruction, but strLength
stays consistent, so the effect is removed.
How come?
Upvotes: 0
Views: 48
Reputation: 385890
usedLength
has the wrong type. It's declared uint32_t
. However, it should be declared NSUInteger
, which is 32 bits on 32 bit architectures and 64 bits on 64 bit architectures.
Upvotes: 2