Ноль в GDB не определяется как 0x0?

Я шел по простому коду Objective-C с помощью gdb (внутри XCode) и заметил кое-что странное. Вот соответствующий фрагмент:

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, отличное от того, которое использует target-C (0x0). Может кто-нибудь объяснить, что здесь происходит?

2 ответа

Решение

Когда ваш код компилируется, nil константа препроцессора, определенная как __null (специальная переменная GCC, которая служит NULL), 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 */

Итак, где же nil откуда берется GDB во время выполнения? Вы можете сказать из сообщения 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

Он указывает на адрес в памяти, а не на содержимое переменной.

Другие вопросы по тегам