2010-11-09 18 views
4

Je passais par un simple code Objective-C avec gdb (à l'intérieur de Xcode) et j'ai remarqué quelque chose d'étrange. Voici l'extrait pertinent:nil dans gdb n'est pas défini comme 0x0?

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

Comme je l'espère, la valeur de x après ces deux lignes est 1. Étrangement, si je tente quelque chose de similaire dans gdb, il ne fonctionne pas le même:

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

Il semble que gdb a une définition pour nulle autre que ce que les utilisations Objective-C (0x0). Quelqu'un peut-il expliquer ce qui se passe ici?

Répondre

9

Lorsque votre code est compilé, nil est une constante de préprocesseur définie pour être soit __null (une variable spéciale de GCC qui sert NULL), 0L ou 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 */ 

Alors, où le nil que gdb ramasse à l'exécution vient? Vous pouvez dire à partir du message gdb donne que nil est le nom d'une variable située à cette adresse:

(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. 

Sa valeur, sans surprise, se révèle être 0:

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

D'où vient cette variable viens de? GDB peut nous dire:

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

En effet, lorsque nous vérifions les symboles définis dans la Fondation, nous trouvons nil:

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

Grande exposition – bacar

1

Il pointe sur l'adresse en mémoire, pas sur le contenu de la variable.