IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Comportement bizarre variables locales et complexes


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 27
    Par défaut Comportement bizarre variables locales et complexes
    Bonjour,

    J'ai des comportement bizarres avec gcc. Cette fonction récupère la position de la souris pour faire un zoom sur une partie de la fractale de Mandelbrot.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    void WMyFrame::OnMouseDown(wxMouseEvent& evt)
    {
        double x = (evt.m_x - iCX) / iLarg * 4.0 * dEchX;
        double y = (evt.m_y - iCY) / iHaut * 4.0 * dEchY;
        complex<double> cb(0.0, 0.0);
     
        ca += complex<double>((evt.m_x - iCX) / iLarg * 4.0 * dEchX,
                              (evt.m_y - iCY) / iHaut * 4.0 * dEchY);
        cb += complex<double>(x, y);
        iCX = int(evt.m_x * dEchX);
        iCY = int(evt.m_y * dEchY);
        dEchX *= 0.20;
        dEchY *= 0.20;
        wxClientDC dc(this);
        Mandel(dc);
    }
    Il y a redondance avec x et y pour mieux expliciter le problème.
    La compilation se fait sans erreurs ni warnings (flag -Wall).

    Avec un breakpoint sur l'appel à Mandel(dc), voici le contenu de la fenêtre watch du debugger gdb 6.3.

    Variables locales
    x = 9.910199999999997
    y = 9.910199999999997
    cb_M_value = 0.0I

    Variable membres de WMyFrame
    dEchX = 0.2
    dEchY = 0.2
    ICX = 169
    iCY = 129
    iLarg = 400
    iHaut = 400
    ca_M_value = 0.0I

    En fait on constate que ni x ni y ne sont calculés ils devraient être à -0.51 et -0.71 respectivement compte tenu des valeurs de evt.m_x et evt.m_y.
    Parfois ils sont déclarés inconnus dans ce scoop !

    Les complexes ca et cb (initialisés à (0.0, 0.0i)) restent à 0.

    Les autres variables membres sont correctes.

    Je n'y comprends rien ! Il arrive également que dans d'autres fonctions membres de WMyFrame, des variables locales soient déclarées inconnues dans ce scoop par le gdb.
    Les variables membres sont toujours reconnues, mais pas toujours calculées comme ici avec le complexe ca.

    Si quelqu'un a une réponse ou un conseil je le remercie par avance

    JP51

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 464
    Par défaut
    peut-être des données debug incomplètes dans l'exécutable, ou mal synchronisées (avec le(s) source(s)) ?

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Par défaut
    Ça peut aussi être dû au débuggage d'un programme compilé avec des optimisations : le compilateur a tendance a optimiser les lignes de code dont il peut se passer. Vérifies que tu compiles bien avec -O0 quand tu utilises le debugger.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 27
    Par défaut
    Citation Envoyé par roulious
    Ça peut aussi être dû au débuggage d'un programme compilé avec des optimisations : le compilateur a tendance a optimiser les lignes de code dont il peut se passer. Vérifies que tu compiles bien avec -O0 quand tu utilises le debugger.
    Non vérification faite le gdb était sans optimisation.

    Par contre j'ai trouvé la solution partielle au mystère dans l'expression de calcul des membres du complexe il faut caster double(evt.m_x - iCX) bien que l'on ait des doubles plus loin dans la même expression ! Il me semblait qu'en C, C++ le type de tous les opérandes était aligné sur celui de plus grande précision.

    Merci

    Jp

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    633
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 633
    Par défaut
    Bonjour,
    Citation Envoyé par jvpic
    Non vérification faite le gdb était sans optimisation.

    Par contre j'ai trouvé la solution partielle au mystère dans l'expression de calcul des membres du complexe il faut caster double(evt.m_x - iCX) bien que l'on ait des doubles plus loin dans la même expression ! Il me semblait qu'en C, C++ le type de tous les opérandes était aligné sur celui de plus grande précision.

    Merci

    Jp
    C'est effectivement le cas, mais il te faut quand même caster double(evt.m_x - iCX),
    car en fait cela fait partie d'une expression qui est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        double x = (evt.m_x - iCX) / iLarg * 4.0 * dEchX;
    et réfléchissons:
    (evt.m_x - iCX) : les 2 termes sont des entiers ==> résultat = entier
    (evt.m_x - iCX) / iLarg : on a donc un entier divisé par un entier ==> division entière
    ...
    Le problème est dû à la priorité des opérateurs: cette division est faite avant qu'apparaisse le * 4.0 qui va forcer le passage en réels (accessoirement, comme tu ne précise pas la taille du 4.0, on se contente de passer en float, la conversion en double se faisant plus tard [mais ça dépend peut-être du compilateur ?]).

    Donc à retenir, pour les divisions : si les 2 termes sont entiers, il faut en caster au moins 1 pour que la division donne une valeur réelle.
    Faire le cast après la division est trop tard, elle s'est faite comme une division entière.

    ps : tu as sans le moindre doute sur la ligne suivante, qui fait un calcul similaire avec les Y

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Une variable boléenne qui se comporte bizarrement
    Par renaud26 dans le forum Général JavaScript
    Réponses: 0
    Dernier message: 05/11/2014, 18h28
  2. Comportement bizarre d'une variable dynamique
    Par scoutiste dans le forum Débuter
    Réponses: 4
    Dernier message: 21/08/2013, 13h36
  3. [Parsing] Comportement bizarre, variable $PATH
    Par Rawkins dans le forum Débuter
    Réponses: 3
    Dernier message: 03/01/2012, 00h34
  4. Comportement bizarre de variables d'applications
    Par ahage4x4 dans le forum ASP
    Réponses: 2
    Dernier message: 14/11/2005, 11h51
  5. variables locales ou globales ???
    Par elvivo dans le forum C
    Réponses: 13
    Dernier message: 03/07/2002, 08h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo