【发布时间】:2009-08-04 18:44:11
【问题描述】:
我最近浪费了大约半个小时来追踪 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=(null)”。
显然,用%d 打印long long 是一个错误,但有人可以解释为什么它会导致text 被打印为空吗?
【问题讨论】:
-
如果你用 -Wall 选项编译,编译器会警告你这样的问题;我也强烈推荐使用 -Werror,这样警告总是会破坏构建。
-
@Adam Rosenfield,请注意,对格式检查的支持,ala
-Wformat,在 gcc/objc 中一直有点狡猾。这似乎在使用更高版本的编译器时变得更好,但我只是在 Xcode 3.1 下快速检查了一下,并没有发现上述错误。 -
它不会捕获错误,因为 -Wformat 仅适用于 C 字符串(如在 printf 中)并且完全无法解析 NSString* 对象常量(NSLog 使用)。
-
@johne,Err,不,他们从 leopard 开始就有这个 NSString 说明符,但它不仅仅是靠不住的,它被默默地忽略了。
-
@Jason Coco,对于随 Xcode 发布版本一起提供的预打包编译器,您可能是对的——因为不稳定,他们只是默默地吞下它。但是获取编译器源代码的副本并进行查看。它就在那里,如果你很聪明,你甚至可以让它承认它所做的不仅仅是“忽略”它。我不记得为什么它一开始就不稳定了。不过,总结是这样的:您很可能会在未来看到
printf之类的(CF|NS)String字符串格式检查,可能是10.6。其中很大一部分已经存在。
标签: objective-c formatting stack printf nslog