Warning: Statement with no effect pour une boucle for(i; i

ClicCoolClicCool Membre
novembre 2009 modifié dans API AppKit #1
Bonjour,

Je me retrouve avec un warning que je pige pas  :-\\

Au Build And Analyse j'ai le warning "[tt]Statement with no effect[/tt]" sur la ligne for(...) ci dessous:
UInt whatToImport = 0;<br />for (whatToImport; whatToImport&lt;11; whatToImport++) {<br />.../...<br />}


Elle est pas belle ma boucle ?  ???

Réponses

  • AliGatorAliGator Membre, Modérateur
    novembre 2009 modifié #2
    Nan, elle est pas belle ta boucle :) ;D

    Bon, en fait, rien qu'en lisant le titre j'aurais dit "toi, t'as mis un point-virgule à  la fin de ton "for(...,...,...);" du coup il te signale que t'as une boucle vide !"... et raté, c'était même pas ça ;D

    En fait le warning me semble clair : tu as, dans ta ligne de ta boucle for, une instruction qui ne sert à  rien, car n'a aucun effet. Et cette instruction, c'est évidemment le "whatToImport" que tu as mis tout seul au début et qui ne sert à  rien car il ne définit pas de variable ni d'affecte de valeur...

    Si ça te permet d'y voir plus clair, n'oublies pas que
    for(&lt;a&gt;;&lt;b&gt;;&lt;c&gt;) { &lt;d&gt;; }
    
    est équivalent à 
    &lt;a&gt;;<br />while(&lt;b&gt;)<br />{<br />  &lt;d&gt;;<br />  &lt;c&gt;;<br />}
    
    C'est à  dire que la première instruction [tt]<a>[/tt] sert à  initialiser tes variables, [tt]<b>[/tt] au test, [tt]<c>[/tt] à  l'instruction à  exécuter juste avant de reboucler (typiquement une incrémentation), et [tt]<d>[/tt] est le corps de ta boucle.

    Là  ton instruction [tt]<a>[/tt] ne fait rien, c'est juste comme si tu écrivais, sur une ligne toute seule, un
    whatToImport;
    
    qui ne fait rien !

    Donc soit tu initialises ton whatToImport dans le for
    UInt whatToImport;<br />for(whatToImport=0;whatToImport&lt;11; whatToImport++) { ... }
    
    quitte à  déclarer whatToImport dans l'instruction d'initialisation du for aussi :
    for(UInt whatToImport=0;whatToImport&lt;11; whatToImport++) { ... }
    
    comme ça au moins la première instruction sert à  qqch... soit tu ne mets rien comme première instruction dans ton for puisque tu l'as déjà  initialisé plus haut :
    UInt whatToImport = 0;<br />for(;whatToImport&lt;11; whatToImport++) { ... }
    
  • ClicCoolClicCool Membre
    novembre 2009 modifié #3
    dans 1257415452:
    .../...
    Rien qu'en lisant le titre j'aurais dit "toi, t'as mis un point-virgule à  la fin de ton "for(...,...,...);" du coup il te signale que t'as une boucle vide ! ;D"... et raté, c'était même pas ça ^^

    Eh Oh, si t'avais lu l'auteur aussi t'aurais jamais pensé ça !  :P

    Si ?  :-\\
    Ah bon !  :P



    dans 1257415452:
    .../...
    UInt whatToImport = 0;<br />for(;whatToImport&lt;11; whatToImport++) { ... }
    


    Ah MERCI!  :o
    Comme un ballot je pensais 'statement' comme la ligne entière et non pas pensé à  chacun des 3 'statements' inclus !

    Bon alors OK, elle est fonctionnelle mais elle est pas belle ma boucle  >:)
    Pourtant je trouve plus clair à  la lecture d'écrire ainsi.
    C'est grave docteur ?
    ça ralenti l'exécution ?


    PS, de toutes façon je vais faire comme t'as dit pour plus avoir ce warning qui fait tache, j'aime mieux voir le rassurant bandeau vert "No Issue" dans mes Build Results  ;)
  • AliGatorAliGator Membre, Modérateur
    21:51 modifié #4
    Moi non plus j'aime pas cette syntaxe, que je n'utilise jamais.
    C'est pour ça que j'utilise une des deux autres que je t'ai proposées, déclarer ta variable avant ton for et l'initialiser dans ton for, ou déclarer et initialiser tout dans ton for.

    Enfin après à  toi de voir... tu mets à  l'intérieur de ton for ou pas, comme tu le sens... dans ton for(t) intérieur ;D
  • ClicCoolClicCool Membre
    novembre 2009 modifié #5
    dans 1257417185:
    .../... ou déclarer et initialiser tout dans ton for.
    Enfin tu fais comme tu le sens... dans ton for(t) intérieur ;D


    J'savais même pô qu'on pouvait déclarer des variables dans un For ... ou alors j'ai oublié ... j'ai jamais tué d'chat ... Ou i sentait pas bon ...









    [EDIT](reminiscences de Jacques Brel ...)
  • mpergandmpergand Membre
    21:51 modifié #6
    Cette syntaxe est possible en C++ en standard, en C il faut choisir C Language dialect C99 dans les options du compilateur.
  • ClicCoolClicCool Membre
    21:51 modifié #7
    dans 1257422093:

    Cette syntaxe est possible en C++ en standard, en C il faut choisir C Language dialect C99 dans les options du compilateur.


    Un peu trop tordu pour moi, mais bon à  savoir.

    Merci :)
  • AliGatorAliGator Membre, Modérateur
    21:51 modifié #8
    Bah en fait je crois que l'Objective-C est basé sur le C99, ce qui permet entre autres de déclarer des variables en plein milieu du code et pas forcément au début du bloc, et aussi de déclarer ses variables ainsi dans les boucles for du coup.
    En tout cas en déclarant ma variable directement dans le "for" dans mes projets Xcode en Objective-C, je n'ai jamais eu de soucis et aucune gueulante du compilateur.

    Par contre si je code en C ANSI (comme il m'arrive de temps en temps de faire un ".c" via vi et de le compiler via le terminal pvia gcc ensuite), là  oui en effet cette syntaxe n'est pas autorisée et l'on est obligés de déclarer toutes nos variables en début de bloc et pas n'importe où, boucle for ou pas.
    Mais bon je fais quand même 1000x plus d'Objective-C que je ne fais du C ANSI ;D
  • mpergandmpergand Membre
    novembre 2009 modifié #9
    dans 1257423218:

    Bah en fait je crois que l'Objective-C est basé sur le C99


    Pas jusqu'à  Leopard  en tout cas:
    Compiler Default: Tells the compiler to use its default C language dialect. This is normally the best choice unless you have specific needs. (Currently equivalent to GNU89.)


    [EDIT]

    en fait je crois que c'est C89 pour les compilos <=4.0 et C99 au dessus (Xcode 3)
  • AliGatorAliGator Membre, Modérateur
    21:51 modifié #10
    Bizarre, j'en mettrais pas ma main à  couper, mais comme j'ai quasiment toujours ou presque codé mes boucles for en déclarant la variable dedans (et non avant), et que je n'ai jamais eu de soucis, même quand je développais en Objective-C sous Tiger pour Mac, ... du coup ça m'étonne.

    Ou alors c'est une tolérance de l'Objective-C, tolérance empruntée au C99 donc, que d'accepter ces déclarations dans le for ?

    par contre, dans un switch sans bloc d'accolades, là  c'est interdit (et qd ça m'est arrivé j'ai mis du temps à  capter) :
    switch(toto)<br />{<br />&nbsp; case 0:<br />&nbsp; &nbsp; int dummy = 0; // interdit<br />&nbsp; &nbsp; break;<br />&nbsp; case 1:<br />&nbsp; {<br />&nbsp; &nbsp; int dummy2 = 1; // ok car on a ouvert une accolade<br />&nbsp; &nbsp; ...<br />&nbsp; }<br />&nbsp; break;<br />} // fin du switch
    
  • Philippe49Philippe49 Membre
    21:51 modifié #11
    dans 1257423218:


    Par contre si je code en C ANSI (comme il m'arrive de temps en temps de faire un ".c" via vi et de le compiler via le terminal pvia gcc ensuite), là  oui en effet cette syntaxe n'est pas autorisée et l'on est obligés de déclarer toutes nos variables en début de bloc et pas n'importe où, boucle for ou pas.
    Mais bon je fais quand même 1000x plus d'Objective-C que je ne fais du C ANSI ;D

    Non les variables en début de bloc ne sont plus obligatoires depuis le C95. Heureusement d'ailleurs.

    Pour autoriser la syntaxe for(int ...), il faut effectivement demander le C99, et là  souvent il faut mettre -std=C99 comme option de compilation.

    Quand au C ANSI, il y a vraiment des pros qui utilisent encore ce vieux truc ?
  • Philippe49Philippe49 Membre
    21:51 modifié #12
    dans 1257425235:

    dans 1257423218:

    Bah en fait je crois que l'Objective-C est basé sur le C99


    Pas jusqu'à  Leopard  en tout cas:
    Compiler Default: Tells the compiler to use its default C language dialect. This is normally the best choice unless you have specific needs. (Currently equivalent to GNU89.)


    [EDIT]

    en fait je crois que c'est C89 pour les compilos <=4.0 et C99 au dessus (Xcode 3)


    Oui il y a une option de cochée par défaut dans les Infos pour que le C99 soit opérationnel.
  • Philippe49Philippe49 Membre
    novembre 2009 modifié #13
    dans 1257427550:

    Ou alors c'est une tolérance de l'Objective-C, tolérance empruntée au C99 donc, que d'accepter ces déclarations dans le for ?

    par contre, dans un switch sans bloc d'accolades, là  c'est interdit (et qd ça m'est arrivé j'ai mis du temps à  capter) :
    switch(toto)<br />{<br />&nbsp; case 0:<br />&nbsp; &nbsp; int dummy = 0; // interdit<br />&nbsp; &nbsp; break;<br />&nbsp; case 1:<br />&nbsp; {<br />&nbsp; &nbsp; int dummy2 = 1; // ok car on a ouvert une accolade<br />&nbsp; &nbsp; ...<br />&nbsp; }<br />&nbsp; break;<br />} // fin du switch
    




    Il y a une certaine logique dans cette obligation du compilateur : en effet on peut très bien ne pas mettre de break à  la fin d'un case, auquel cas les lignes de code du case suivant sont exécutées. Dès lors la portée de la variable créée est imprécise.

    <br />switch(expression){<br />&nbsp;  case Il_y_a_un_prenom:<br />&nbsp; &nbsp; &nbsp; &nbsp;  int dummy=0;&nbsp; &nbsp; &nbsp; // sera-t-elle valide dans le second case ?<br />&nbsp; &nbsp; &nbsp; &nbsp;  printf(&quot;%s&#092;t&quot;,prenom);<br />&nbsp; &nbsp; &nbsp; &nbsp;  // pas de break donc les instructions du case suivant sont réalisées<br />&nbsp;  case Il_y_a_un_nom:<br />&nbsp; &nbsp; &nbsp; &nbsp;  printf(&quot;%s&#092;t&quot;,nom);<br />&nbsp; &nbsp; &nbsp; &nbsp;  break;<br />...<br />
    
  • AliGatorAliGator Membre, Modérateur
    21:51 modifié #14
    Oui oui tout à  fait d'accord, c'est parfaitement logique... Seulement le jour où ça m'est arrivé qu'il me gueule dessus j'ai mis du temps à  capter que c'était pour ça ;)
Connectez-vous ou Inscrivez-vous pour répondre.