gdb中的nil没有定义为0x0?

发布于 2024-10-01 10:36:47 字数 466 浏览 4 评论 0原文

我正在使用 gdb(在 Xcode 内部)单步执行一些简单的 Objective-C 代码,并注意到一些奇怪的事情。这是相关的片段:

NSString *s = nil;
int x = (s == nil);

正如我所期望的,这两行之后的 x 的值为 1。奇怪的是,如果我在 gdb 中尝试类似的东西,它的工作方式并不相同:

(gdb) print ret
$1 = (NSString *) 0x0
(gdb) print (int)(ret==nil)
$2 = 0
(gdb) print nil
$3 = {<text variable, no debug info>} 0x167d18 <nil>

看起来 gdb 对 nil 有一些定义,而不是 Objective-C 使用的(0x0)。有人能解释一下这是怎么回事吗?

I was stepping through some simple Objective-C code with gdb (inside of Xcode) and noticed something strange. Here is the relevant snippet:

NSString *s = nil;
int x = (s == nil);

As I'd expect, the value of x after these two lines is 1. Strangely, if I try something similar in gdb, it doesn't work the same:

(gdb) print ret
$1 = (NSString *) 0x0
(gdb) print (int)(ret==nil)
$2 = 0
(gdb) print nil
$3 = {<text variable, no debug info>} 0x167d18 <nil>

It seems like gdb has some definition for nil other than what objective-C uses (0x0). Can someone explain what's going on here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最美的太阳 2024-10-08 10:36:47

当你的代码被编译时,nil是一个预处理器常量,定义为__null(一个特殊的GCC变量,充当NULL),< code>0L 或 0

<objc/objc.h>
#ifndef nil
#define nil __DARWIN_NULL /* id of Nil instance */
#endif

<sys/_types.h>
#ifdef __cplusplus
#ifdef __GNUG__
#define __DARWIN_NULL __null
#else /* ! __GNUG__ */
#ifdef __LP64__
#define __DARWIN_NULL (0L)
#else /* !__LP64__ */
#define __DARWIN_NULL 0
#endif /* __LP64__ */
#endif /* __GNUG__ */
#else /* ! __cplusplus */
#define __DARWIN_NULL ((void *)0)
#endif /* __cplusplus */

那么,gdb 在运行时获取的 nil 从哪里来呢?您可以从 gdb 给出的消息中看出 nil 是位于该地址的变量的名称:

(gdb) p nil
$1 = {<text variable, no debug info>} 0x20c49ba5da6428 <nil>
(gdb) i addr nil
Symbol "nil" is at 0x20c49ba5da6428 in a file compiled without debugging.

不出所料,它的值是 0

(gdb) p *(long *)nil
$2 = 0
(gdb) x/xg nil
0x20c49ba5da6428 <nil>: 0x0000000000000000

这个变量在哪里来自? GDB可以告诉我们:

(gdb) i shared nil
  3 Foundation        F -                 init Y Y /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation at 0x20c49ba5bb2000 (offset 0x20c49ba5bb2000)

确实,当我们检查Foundation中定义的符号时,我们发现nil

$ nm -m /System/Library/Frameworks/Foundation.framework/Foundation | grep nil$
00000000001f4428 (__TEXT,__const) external _nil

When your code is being compiled, nil is a preprocessor constant defined to be either __null (a special GCC variable that serves as NULL), 0L, or 0:

<objc/objc.h>
#ifndef nil
#define nil __DARWIN_NULL /* id of Nil instance */
#endif

<sys/_types.h>
#ifdef __cplusplus
#ifdef __GNUG__
#define __DARWIN_NULL __null
#else /* ! __GNUG__ */
#ifdef __LP64__
#define __DARWIN_NULL (0L)
#else /* !__LP64__ */
#define __DARWIN_NULL 0
#endif /* __LP64__ */
#endif /* __GNUG__ */
#else /* ! __cplusplus */
#define __DARWIN_NULL ((void *)0)
#endif /* __cplusplus */

So, where does the nil that gdb picks up at runtime come from? You can tell from the message gdb gives that nil is the name of a variable located at that address:

(gdb) p nil
$1 = {<text variable, no debug info>} 0x20c49ba5da6428 <nil>
(gdb) i addr nil
Symbol "nil" is at 0x20c49ba5da6428 in a file compiled without debugging.

Its value, unsurprisingly, turns out to be 0:

(gdb) p *(long *)nil
$2 = 0
(gdb) x/xg nil
0x20c49ba5da6428 <nil>: 0x0000000000000000

Where does this variable come from? GDB can tell us:

(gdb) i shared nil
  3 Foundation        F -                 init Y Y /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation at 0x20c49ba5bb2000 (offset 0x20c49ba5bb2000)

Indeed, when we check the symbols defined in Foundation, we find nil:

$ nm -m /System/Library/Frameworks/Foundation.framework/Foundation | grep nil$
00000000001f4428 (__TEXT,__const) external _nil
无力看清 2024-10-08 10:36:47

它指向内存中的地址,而不是变量内容。

It's pointing to the address in memory, not the variable contents.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文