Problème floatValue sur object nil

Bonsoir,

Je souhaiterais attirer votre attention sur un petit problème...

Je ne comprends pas pourquoi le second renvoit 0 alors que le floatvalue renvoit n'importe quoi... D'origine le nil est un NSNumber.

NSLog(@la %f,[nil floatValue]);
NSLog(@la %d,[nil intValue]);

Merci...

Réponses

  • amnesicamnesic Membre
    21:58 modifié #2
    dans 1126545466:

    D'origine le nil est un NSNumber.


    tu veux dire que tu as crée un variable nil ? nil est un mot clé reservé non ?
  • 21:58 modifié #3
    NSNumber *n=nil;
    NSLog(@la %f,[n floatValue]);
    NSLog(@la %d,[n intValue]);
  • mpergandmpergand Membre
    septembre 2005 modifié #4
    Parce que ça retourne nil ?

    :)
  • amnesicamnesic Membre
    21:58 modifié #5
    dans 1126546418:

    NSNumber *n=nil;
    NSLog(@la %f,[n floatValue]);
    NSLog(@la %d,[n intValue]);



    Attention tu ne créer pas d'objet avec "NSNumber *n=nil;" il faudrait faire un truc du genre :
    NSNumber *n= [NSNumber numberWithInt:nil];

  • 21:58 modifié #6
    Mouais d'accord, je sais très bien que je ne crée pas d'objet. Je récupère le NSNumber d'un NSDictionary, jusqu'à  présent je ne testais pas si NSNumber pour savoir s'il vallait nil puisque j'avais pris l'habitude d'avoir 0 dans ce cas, mais le problème c'est que c'est valable avec intValue mais pas floatValue...

    Essayez :
    NSLog(@la %f,nil);
    NSLog(@la %d,nil);

    Et la ça affiche bien 0.0 dans les deux cas. Chose que je n'ai pas avec [nil floatValue] d'ou mon post... (nil n'est pas un nom d'objet, nil c'est nil et personne d'autre).
  • ChachaChacha Membre
    21:58 modifié #7
    Salut,
    Je pense que ton code est plantogène.
    Je m'explique : en Objective-C, il est légal d'envoyer un message à  nil. Par contre, il est illégal d'essayer d'en récupérer une valeur de retour : il ne peut pas y en avoir.
    Pourtant, de ce que j'en ai vu, si la valeur renvoyée est un objet, alors il semblerait que ça marche, on récupère bien nil.
    Mais quand c'est autre chose qu'un objet (genre un in ou un float), alors là  on récupère n'importe quoi, et à  mon avis il y a une corruption de la mémoire qui est faite. Du coup, même si ça ne plante pas immédiatement, il est probable que le programme devienne instable, avec des données indésirablement modifiées.
    Donc même si dans ton cas, le int renvoie 0 et le float n'importe quoi, je dirais que c'est un coup de chance pour le int. En d'autres circonstances, le int aurait affiché n'importe quoi aussi.
    Quoi qu'il en soit : éviter de récupérer une valeur qui ne soit pas un objet si le message risque d'être envoyé sur nil.
    +
    Chacha
  • amnesicamnesic Membre
    21:58 modifié #8
    dans 1126557887:

    Et la ça affiche bien 0.0 dans les deux cas. Chose que je n'ai pas avec [nil floatValue] d'ou mon post... (nil n'est pas un nom d'objet, nil c'est nil et personne d'autre).


    Pour info moi ici j'ai bien zéro dans les 2 cas par exemple (pur hasard trompeur) ... bref comme l'explique Chacha ton code est "plantogène".
    (d'ailleurs tu as un warning "warning: invalid receiver type 'int'" qui te le signal)
  • AliGatorAliGator Membre, Modérateur
    21:58 modifié #9
    Suggestion (je suis pas sûr de mon coup mais ça pourrait être une explication)

    [nil intValue] renvoie peut-être NULL = (void*)0 qui, casté en int, affiche zéro...
    Pure spéculation bancale, hein...
  • septembre 2005 modifié #10
    dans 1126561520:

    dans 1126557887:

    Et la ça affiche bien 0.0 dans les deux cas. Chose que je n'ai pas avec [nil floatValue] d'ou mon post... (nil n'est pas un nom d'objet, nil c'est nil et personne d'autre).


    Pour info moi ici j'ai bien zéro dans les 2 cas par exemple (pur hasard trompeur) ... bref comme l'explique Chacha ton code est "plantogène".
    (d'ailleurs tu as un warning "warning: invalid receiver type 'int'" qui te le signal)


    Tu veux dire sur
    NSNumber *n=nil;<br />NSLog(@&quot;la %f&quot;,[n floatValue]);<br />NSLog(@&quot;la %d&quot;,[n intValue])
    

    ou sur
    NSLog(@&quot;la %f&quot;,nil);<br />NSLog(@&quot;la %d&quot;,nil)
    
    ?

    Je sais très bien que j'ai un warn sur [nil floatValue] mais là  c'était pour raccourcir... il n'est pas dans un programme...

    Chacha, ok je veux bien supposer, mais quand par exemple avec un stringValue effectué sur un NSTextField qui vaut nil, tu as forcément une chaine nil ? Non ? intValue a toujours renvoyer 0 alors que floatValue, doubleValue, affichent des valeurs bidons... je parle sur mon iBook G4... pas la chance d'avoir un G5... Puisqu'on peut envoyer un message à  nil je ne comprends pas pourquoi dans certains cas on récupère autre chose que nil.

    Abligator, donc :
    void *ptr=NULL;<br />NSLog(@&quot;la %f&quot;,ptr);
    

    Ne serait pas bon d'après toi... mais il affiche 0.0 à  tous les coups sur mon ibook.

    Ou même 
    NSLog(@&quot;la %d&quot;,[ptr intValue]);
    
  • ChachaChacha Membre
    21:58 modifié #11
    dans 1126595489:

    Chacha, ok je veux bien supposer, mais quand par exemple avec un stringValue effectué sur un NSTextField qui vaut nil, tu as forcément une chaine nil ? Non ?

    Oui, avec un stringValue sur un NSTextField nil, on récupère nil, parce que c'est un objet. Or nil, vaut 0, donc on devrait obtenit 0 pour un int aussi, non ? Et bien non, je ne suis pas trop d'accord.
    D'un point de vue assembleur, les résultats d'une fonction vont se retrouver sur la pile d'appel. Donc si on essaye de récupérer un int, ça ne va pas, vu que le message a été envoyé à  nil, et que aucun int n'a été déposé sur la pile. Donc si on lit quand même ce qui s'y trouve, on ne lit pas "au bon endroit" de la pile, donc on lit n'importe quoi. Et même en supposant que l'appel ait déposé nil (soit la valeur 0 sur 4 octets (en 32 bits) ou sur 8 octets (en 64 bits)), cette taille en octets ne correspondont pas forcément à  ce que tu essayes de lire. Par exemple, si ta fonction devait renvoyer une struct de 10 octets ?

    Par contre, vu qu'on récupère toujours nil si la fonction devait renvoyer un objet, je me demande si le système d'appel dynamique de l'objective-C est différent du schéma classique de la pile d'appel. C'est possible, pour des raisons d'efficacité. Je me demande à  quel point ça vient de l'architecture PowerPC ou du moteur Objective-C.

    +
    Chacha
  • 21:58 modifié #13
    C'est pas marrant :(

    ;)
  • ChachaChacha Membre
    août 2006 modifié #14
    Salut,

    En consultant un blog que je ne connaissais pas, je trouve la réponse à  ce vieux fil de discussion qui nous taraudait tous : que récupère-t-on si on appelle une méthode sur nil ? ça dépend du type de retour ? Et bien oui !
    http://ridiculousfish.com/blog/archives/2005/05/29/nil/
    Ce blog est un blog technique et excellent ! D'ailleurs, ceci devrait vous convaincre :

    I'm a developer on Apple's AppKit team; I work to make Cocoa better. With a few exceptions, we are responsible for both AppKit and Foundation. This is my blog.


    Alors allez vous abreuver de nombreuses infos très précieuses !
    Envoyer nil à  un objet ? (explications pour PowerPC!)
    Comment est implémenté un NSArray, et que peut-on en attendre ?
    Comment accélérer le objc_msgSend d'Objective-C ?
    etc.

    Bonne lecture

    +
    Chacha
  • BruBru Membre
    21:58 modifié #15
    dans 1156274660:

    En consultant un blog que je ne connaissais pas, je trouve la réponse à  ce vieux fil de discussion qui nous taraudait tous : que récupère-t-on si on appelle une méthode sur nil ? ça dépend du type de retour ? Et bien oui !
    http://ridiculousfish.com/blog/archives/2005/05/29/nil/


    Je connais ce site : un des meilleurs.

    C'est là  où j'ai pu glaner une réponse précise au pourquoi de l'interdiction des fonctions imbriquées depuis GCC 4 (voir ce post).

    A mettre dans ces favoris.

    .
Connectez-vous ou Inscrivez-vous pour répondre.