NSLog(...)不正确的格式说明符影响其他变量? [英] NSLog(...) improper format specifier affects other variables?
问题描述
我最近浪费了大约半个小时的时间,在NSLog中追踪这个奇怪的行为:
NSString * text = @abc;
long long num = 123;
NSLog(@num =%lld,text =%@,num,text); //(A)
NSLog(@num =%d,text =%@,num,text); (B)
行(A)打印预期的num = 123,text = abc ,但行(B)打印num = 123,text = (空)。
显然,打印 long long
with %d
是一个错误,但是有人可以解释为什么它会导致 text
打印为空?
我认为比你使用x86处理器的最新苹果产品。考虑到这些假设你的堆栈看起来就像在这两种情况下:
|堆栈|第一|秒|
+ --------------------- + ------- + -------- +
| 123 | | %d |
+ --------------------- +%lld + -------- +
| 0 | | %@ |
+ --------------------- + ------- + -------- +
|指向文本|的指针%@ |被忽略|
+ --------------------- + ------- + -------- +
在第一种情况下,您将堆栈8个字节,然后4个字节。并且NSLog被指示从堆栈12个字节( / code>到 Objective-C只是C的补充,调用者清理整个这个烂摊子。 %lld
8字节,%@
4字节) )。
$ b 在第二种情况下,指示NSLog首先占用4个字节(%d
)。由于你的变量是8个字节长,并且保存的数字非常小,所以它的高4字节将是0.然后,当NSLog将尝试打印文本时,它将从堆栈中取 nil
因为发送消息到 nil
在Obj-C中是有效的NSLog只会发送描述:
nil
可能没有任何东西,然后print(null)。
I recently wasted about half an hour tracking down this odd behavior in NSLog(...):
NSString *text = @"abc";
long long num = 123;
NSLog(@"num=%lld, text=%@",num,text); //(A)
NSLog(@"num=%d, text=%@",num,text); //(B)
Line (A) prints the expected "num=123, text=abc", but line (B) prints "num=123, text=(null)".
Obviously, printing a long long
with %d
is a mistake, but can someone explain why it would cause text
to be printed as null?
You just messed up memory alignment on your stack. I assume than you use newest Apple product with x86 processor. Taking these assumptions into account your stack looks like that in both situations:
| stack | first | second | +---------------------+-------+--------+ | 123 | | %d | +---------------------+ %lld +--------+ | 0 | | %@ | +---------------------+-------+--------+ | pointer to text | %@ |ignored | +---------------------+-------+--------+
In first situation you put on stack 8 bytes and then 4 bytes. And than NSLog is instructed to take back from stack 12 bytes (8 bytes for %lld
and 4 bytes for %@
).
In second situation you instruct NSLog to first take 4 bytes (%d
). Since your variable is 8 bytes long and holds really small number its upper 4 bytes will be 0. Then when NSLog will try to print text it will take nil
from stack.
Since sending message to nil
is valid in Obj-C NSLog will just send description:
to nil
get probably nothing and then print (null).
In the end since Objective-C is just C with additions, caller cleans up whole this mess.
这篇关于NSLog(...)不正确的格式说明符影响其他变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!