Problème avec le type de base int

GreensourceGreensource Membre
23:46 modifié dans API AppKit #1
Bonjour, j'ai un souci vraiment étrange.
Je vais essayer d'être le plus clair possible. J'ai fait une classe GWcoordinate avec deux attributs x et y de type int:
@interface GWCoordinate : NSObject {<br />	int x;<br />	int y;<br />}<br />- (id)init;<br />- (id)initWithX:(int)abs Y:(int)ord;<br />@property (readwrite) int x,y;<br />@end

Le souci c'est que quand j'instancie un objet GWCoordinate avec initWithX:Y: et bien la valeur du int devient n'importe quoi! du genre 15261951 alors que j'ai passer 1 en paramètre!
GWCoordinate *coord;<br />coord = [[GWCoordinate alloc] initWithX:i Y:1];

Je ne comprend pas, je me disais que les type de base étais ce qu'il y a de plus simple mais là , comprend pas. Si j'avais mis une valeur négative pourquoi pas mais là  non je met 1, ça ne peut-être qu'un int!
Vous y comprenez quelques choses?
«1

Réponses

  • CéroceCéroce Membre, Modérateur
    23:46 modifié #2
    Non, je ne comprends pas non plus, mais ce que j'aimerais savoir c'est comment tu fais pour connaà®tre la valeur de x et y ? Avec des NSlog, au débogueur ?
  • GreensourceGreensource Membre
    23:46 modifié #3
    Oui j'ai implémenter description pour GWCoordinate. Et aussi via le debuggeur d'ailleurs. C'est chelou ce truc, je vais me faire des tests et essayer de comprendre...
  • GreensourceGreensource Membre
    23:46 modifié #4
    Résolu!
    C'est visiblement le nom de ma méthode d'init qui n'étais pas bon.
    Elle s'appelait: initWithX:Y:
    et j'avais un attribut x et un autre y, ça venait peut-être de ça.
    Merci céroce
  • Philippe49Philippe49 Membre
    23:46 modifié #5
    dans 1235155849:

    Résolu!
    C'est visiblement le nom de ma méthode d'init qui n'étais pas bon.
    Elle s'appelait: initWithX:Y:

    Cela n'était surement pas la cause.
    C'est sans doute le genre de bug qu'on a du mal à  trouver parce qu'on n'imagine pas avoir fait un truc pareil. par exemple, je vois dans ton premier post :
    coord = [[GWCoordinate alloc] initWithX:i Y:1];
    si i n'est pas initialisé, ou si c'est un float, ou si ... alors il peut être mal lu



  • AliGatorAliGator Membre, Modérateur
    23:46 modifié #6
    En même temps on a pas vu la tronche de son implémentation de son [tt]initWithX:Y:[/tt] c'était p'tet là  dedans qu'il avait une erreur... parce que c'est bien beau de déclarer une méthode [tt]-(void)initWithX:Y:[/tt] mais porter un nom évocateur ne suffit pas... si dans l'implémentation dans le .m elle fait n'importe quoi, forcément, ça va pas aller loin :D
  • GreensourceGreensource Membre
    23:46 modifié #7
    Oui j'aurais dû mettre plus de code, cela aurais été plus explicite. Voici ce qu'il y avais dans la méthode:
    - (id)initWithX:(int)abs Y:(int)ord<br />{<br />	[super init];<br />	x=abs;<br />	y=ord;<br />	return self;<br />}
    

    Pour ce qui est du i dont tu parles, c'était un int initialisé dans un for. Je m'étais d'ailleurs dit que celà  pouvais être la cause, donc j'ai essayer avec des constantes 2 et 3 par exemple, et pareil ça ne marchais pas.
    J'ai suivi ligne par ligne au débuggueur, et c'est bien au moment de passer les param qu'il y avais une erreur, transformation d'un 1 en 15261951 ??? Bizarre hein?
  • Philippe49Philippe49 Membre
    février 2009 modifié #8
    Il faut mettre self=[super init];
  • GreensourceGreensource Membre
    23:46 modifié #9
    Sérieux? Bas je comprends pas, dans le bouquin "Cocoa par la pratique" c'est jamais ce qu'on fait. C'est ma seule référence, mais je fait comme ça et ça marche. En même temps ce que tu me dis me semble plus logique après réflexion.
  • Philippe49Philippe49 Membre
    février 2009 modifié #10
    Effectivement, tu as raison, [super init] est suffisant. Perso je mets self=[super init]; parce que pour moi cela chante mieux, mais ce n'est pas obligatoire.
    Je cherchais une erreur dans ton code ...
  • Philippe49Philippe49 Membre
    23:46 modifié #11
    Voilà  j'ai trouvé

    #include <stdlib.h>
    int main(void) {
    int x=abs;
    printf("%x\n",x);
    return 0;
    }

    Cela écrit l'adresse de la fonction abs() de stdlib.

    Logiquement, il doit y avoir un warning sur cette ligne, non ?
  • schlumschlum Membre
    23:46 modifié #12
    Non, il y a un "abs" dans ses arguments de fonction... Si -Wshadow est spécifié il y aura un warning de shadow, mais sinon non.
    ça prend toujours la référence du scope le plus proche.
  • Philippe49Philippe49 Membre
    23:46 modifié #13
    dans 1235208304:

    Non, il y a un "abs" dans ses arguments de fonction... Si -Wshadow est spécifié il y aura un warning de shadow, mais sinon non.
    ça prend toujours la référence du scope le plus proche.

    Tu dis Non pour le Warning , parce que l'erreur je ne vois d'où elle pourrait venir autrement ?
  • GreensourceGreensource Membre
    23:46 modifié #14
    non je n'avais aucun warning. C'est dingue ce truc qui prend l'adresse d'une fonction! Surtout que cette valeur changeait en fonction de l'entier entré en paramètre.
    Et puis aussi, c'est bizarre puisque j'avais aussi un paramètre "ord" et il déconnait aussi. Je vais allez voir s'il existe dans stdlib...
  • Philippe49Philippe49 Membre
    février 2009 modifié #15
    dans 1235209442:

    non je n'avais aucun warning. C'est dingue ce truc qui prend l'adresse d'une fonction! Surtout que cette valeur changeait en fonction de l'entier entré en paramètre.

    Non, c'est normal, les fonctions ont une adresse :

    #include &lt;stdio.h&gt;<br />#include &lt;stdlib.h&gt;<br />int main(void) {<br />	int x=abs;<br />	printf(&quot;%p&#092;n&quot;,abs);<br />	printf(&quot;%p&#092;n&quot;,div);<br />	printf(&quot;%p&#092;n&quot;,printf);	<br />	printf(&quot;%x&#092;n&quot;,x);<br />	return 0;	<br />}
    


    % gcc pgm.c -o pgm
    pgm.c: In function ‘main':
    pgm.c:4: warning: initialization makes integer from pointer without a cast  # pour x=abs
    % pgm
    0x92a55d7e
    0x92a56fe7
    0x92a58f6b
    92a55d7e
    %

  • schlumschlum Membre
    23:46 modifié #16
    Je viens de tester...

    L'erreur vient bien du nom de la méthode initWithX:Y:
    CIVector en a une du même nom.

    Après je ne saurais pas expliquer pourquoi ça clashe avec.
  • schlumschlum Membre
    23:46 modifié #17
    dans 1235208448:

    dans 1235208304:

    Non, il y a un "abs" dans ses arguments de fonction... Si -Wshadow est spécifié il y aura un warning de shadow, mais sinon non.
    ça prend toujours la référence du scope le plus proche.

    Tu dis Non pour le Warning , parce que l'erreur je ne vois d'où elle pourrait venir autrement ?


    Je dis non surtout pour l'erreur. Je ne vois pas pourquoi il y aurait une erreur, puisqu'il y a un "abs" dans le scope de la méthode !

    On a le droit de nommer dans un scope local des variable abs, printf ou ce qu'on veut quand même  ;)
  • schlumschlum Membre
    février 2009 modifié #18
    dans 1235209442:

    non je n'avais aucun warning. C'est dingue ce truc qui prend l'adresse d'une fonction! Surtout que cette valeur changeait en fonction de l'entier entré en paramètre.
    Et puis aussi, c'est bizarre puisque j'avais aussi un paramètre "ord" et il déconnait aussi. Je vais allez voir s'il existe dans stdlib...


    Pas de "ord" dans la stdlib... De toute manière le problème de vient pas de là  ; on a tout à  fait le droit d'avoir un argument qui s'appelle "abs"  ;)

    Si on a activé "-Wshadow", on aura juste un warning "warning: declaration of ‘abs' shadows a global declaration"
    Ce qui veut dire que si tu essaies d'utiliser la fonction "abs" justement dans ce scope, tu auras des problèmes.



    Mais j'ai déjà  eu ce souci de signatures de méthodes entre classes qui se télescopent ; c'est assez désagréable j'avoue  >:)
    Quand on regarde le fonctionnement interne, l'Objective-C est parfois un beau fouillis quand même.
  • Philippe49Philippe49 Membre
    23:46 modifié #19
    dans 1235209890:

    Je viens de tester...

    L'erreur vient bien du nom de la méthode initWithX:Y:
    CIVector en a une du même nom.

    Après je ne saurais pas expliquer pourquoi ça clashe avec.


    Deux classes différentes ont bien le droit d'avoir le même nom pour une méthode ...
    et en plus cela m'étonnerait que la bibliothèque CoreImage ait été importée dans le projet de GreenSource.


    dans 1235210371:

    De toute manière le problème de vient pas de là  ; on a tout à  fait le droit d'avoir un argument qui s'appelle "abs"  ;)

    Et l'affectation x=abs ?
    Cela demande un essai

  • Philippe49Philippe49 Membre
    23:46 modifié #20
    #include <stdio.h>
    #include <stdlib.h>

    int value(int printf) {
    int x=printf;
    printf("coucou\n");
    return x;
    }
    int main(void) {
    printf("%d\n",value(5));
    return 0;
    }

    % gcc pgm.c -o pgm
    pgm.c: In function ‘value':
    pgm.c:6: error: called object ‘printf' is not a function
    %

    Effectivement, cela masque le nom de fonction
    et sans le printf dans la fonction, cela écrit 5.
  • schlumschlum Membre
    23:46 modifié #21
    dans 1235211305:

    dans 1235210371:

    De toute manière le problème de vient pas de là  ; on a tout à  fait le droit d'avoir un argument qui s'appelle "abs"  ;)

    Et l'affectation x=abs ?
    Cela demande un essai


    Je l'ai fait l'essai...

    J'ai pris son code, même problème, puis j'ai changé le nom de la fonction :
    "initTWithX:Y:" et plus de problème.

    Et on a tout a fait le droit d'avoir "x=abs" quand on a un argument qui s'appelle "abs" voyons  :P
  • schlumschlum Membre
    février 2009 modifié #22
    dans 1235211305:

    Deux classes différentes ont bien le droit d'avoir le même nom pour une méthode ...
    et en plus cela m'étonnerait que la bibliothèque CoreImage ait été importée dans le projet de GreenSource.


    Apparemment, si... Puisque "Jump to Definition" m'a amené à  CIVector quand j'avais l'ancien nom (et absolument aucun warning de "shadow" à  la compilation !).
    Je suppose donc que toutes les signatures sont mélangées et qu'il se mélange les pinceaux quand il va la chercher.

    De toute manière, pour le runtime, les méthodes ne sont absolument pas liées aux classes, d'où le problème je pense.
    Un autre gros effet de bord bordélique du dynamisme de l'Objective-C.
  • Philippe49Philippe49 Membre
    23:46 modifié #23
    dans 1235211574:

    J'ai pris son code, même problème, puis j'ai changé le nom de la fonction :
    "initTWithX:Y:" et plus de problème.

    Incompréhensible

    dans 1235211574:

    Et on a tout a fait le droit d'avoir "x=abs" quand on a un argument qui s'appelle "abs" voyons  :P

    Pas si simple en C, cela pose le problème du choix du masquage des identificateurs au moment de la compilation.   :P
  • Philippe49Philippe49 Membre
    23:46 modifié #24
    dans 1235211723:

    De toute manière, pour le runtime, les méthodes ne sont absolument pas liées aux classes, d'où le problème je pense.
    Un autre gros effet de bord bordélique du dynamisme de l'Objective-C.


    Ben si c'est cela il faut arrêter tout de suite de faire de l'objective-C. Parce que là  c'est n'importe quoi.
    A moins que ce soit un défaut de déclaration dans l'interface qui trompe le compilateur ?
  • schlumschlum Membre
    23:46 modifié #25
    dans 1235211953:

    dans 1235211574:

    Et on a tout a fait le droit d'avoir "x=abs" quand on a un argument qui s'appelle "abs" voyons  :P

    Pas si simple en C, cela pose le problème du choix du masquage des identificateurs au moment de la compilation.   :P


    D'où le warning de shadow quand on met le flag -Wshadow  ;)
    J'active toujours ce warning pour éviter de faire ce genre de chose et avoir des surprises quand j'ai une variable "n" dans un scope et une autre variable "n" dans un sous-scope par exemple.
    Bugs bizarres garantis  :o
  • Philippe49Philippe49 Membre
    23:46 modifié #26
    essaye avec initWithX:(int)xVal Y: (int) yVal; pour voir si on n'a pas un mélange des deux problèmes ?
  • schlumschlum Membre
    23:46 modifié #27
    #import &lt;Foundation/Foundation.h&gt;<br />#import &lt;Cocoa/Cocoa.h&gt;<br /><br />@interface Toto : NSObject {<br />	int x,y;<br />}<br /><br />- (id)initWithX:(int)_x Y:(int)_y;<br /><br />@property (readwrite) int x,y;<br /><br />@end<br /><br />@implementation Toto<br /><br />- (id)initWithX:(int)_x Y:(int)_y<br />{<br />	if((self=[super init])!=nil) {<br />		x = _x;<br />		y = _y;<br />	}<br />	return self;<br />}<br /><br />@synthesize x,y;<br /><br />@end<br /><br />int main (int argc, const char * argv&#91;]) {<br />&nbsp; &nbsp; Toto *t = [[Toto alloc] initWithX:5 Y:1];<br />	NSLog(@&quot;%d,%d&quot;,t.x,t.y);<br />	[t release];<br />&nbsp; &nbsp; return 0;<br />}
    



    [Session started at 2009-02-21 11:36:49 +0100.]
    2009-02-21 11:36:49.852 TestInit[84079:10b] 1,3
  • schlumschlum Membre
    février 2009 modifié #28
    À noter que si je n'inclus que "Foundation" et pas tout "Cocoa", pas de problème !

    Par contre, super bizarre... dans gdb, il passe bien par ma méthode init !! (et affiche un résultat faux derrière...)
  • Philippe49Philippe49 Membre
    23:46 modifié #29
    Ce ne serait pas le @property (readwrite)  ?
    Pour un type simple, on ne voit pas l'intérêt de cet attribut
  • schlumschlum Membre
    février 2009 modifié #30
    Même combat sans utiliser les propriétés...
    De toute manière, le coup de l'import est flagrant. Sans tout Cocoa (et donc CI), pas de soucis.


    #import &lt;Cocoa/Cocoa.h&gt;<br /><br />@interface Toto : NSObject {<br />	int x,y;<br />}<br /><br />- (id)initWithX:(int)_x Y:(int)_y;<br />- (void)printXY;<br /><br />@end<br /><br />@implementation Toto<br /><br />- (id)initWithX:(int)_x Y:(int)_y<br />{<br />	if((self=[super init])!=nil) {<br />		x = _x;<br />		y = _y;<br />	}<br />	return self;<br />}<br /><br />- (void)printXY<br />{<br />	NSLog(@&quot;%d,%d&quot;,x,y);<br />}<br /><br />@end<br /><br />int main (int argc, const char * argv&#91;]) {<br />&nbsp; &nbsp; Toto *t = [[Toto alloc] initWithX:5 Y:1];<br />	[t printXY];<br />	[t release];<br />&nbsp; &nbsp; return 0;<br />}
    


    ->
    2009-02-21 11:59:47.193 TestInit[85165:817] 1,8
    



    Mais je le répète, j'ai déjà  eu ce problème une fois (pas avec "initWithX:Y:")... j'ai pas cherché plus loin à  l'époque, j'ai changé le nom et vala.
  • Philippe49Philippe49 Membre
    23:46 modifié #31
    En mettant  - (id)initWithX:(CGFloat) xVal Y:(CGFloat)yVal comme dans CIVector, ça marche, on a bien le 5 et le 1.
    Y a forcément une erreur quelque part, il ne va pas chercher la signature de CIVector pour l'appliquer à  Toto qui hérite de NSObject !
Connectez-vous ou Inscrivez-vous pour répondre.