2010-02-08 3 views
0

Je programmait une application en C++ Builder 6, et je l'avais rencontré ce problème rare:Pourquoi le compilateur ne compile pas de ligne dans C++ Builder?

void RotateDice() 
{ 
    Graphics::TBitmap *MYbitmap = new Graphics::TBitmap(); 

    Randomize(); 
    int rn = random(6) + 1; 

    switch (rn) 
    { 
    case 1: 
    { 
     //... 
     break; 
    } 
    //... Some cases... 
    } 

    ShowDice(); //it's a function to show the dice 
    delete MYbitmap; //the compiler don't get it!!!! 
} 

Dans la ligne "ShowDice()", le compilateur saute à la finale de la méthode RotateDice(), il ne "voit" pas la ligne "supprimer MYbitmap". Quand je compile le programme, chaque ligne compilée montre un petit point bleu sur son côté gauche, mais cette ligne ne montre pas le point bleu ... c'est comme si le compilateur ne "voyait" pas la ligne de code. Qu'est-ce qui se passe avec ça?

Note: Il y a quelques jours, j'écrivais un programme en Delphi et je conseillais sur ce problème. Certains comme ça m'est arrivé à Delphi 7 ... Alors, quel est le problème avec ça?

Je suis tellement désolé pour mon anglais. Je suis de Cuba.

+0

Remplacer la ligne « supprimer MyBitMap » avec Cout << « quelque chose », exécutez votre programme et vérifiez si vous voyez ce message dans la console. Si vous le voyez alors le problème est avec le débogueur, pas le compilateur, et vous ne devriez pas trop vous inquiéter. Si vous ne voyez pas le message, vous devriez obtenir un meilleur compilateur. – Manuel

+0

Veuillez montrer le code dans ShowDice. –

+0

Avez-vous compilé avec des optimisations? – Bill

Répondre

2

Comme j'ai compris votre problème, lorsque vous tracez votre application, le débogueur "saute" la ligne delete MYbitmap;?

  1. Essayez de placer un point d'arrêt sur cette ligne. Si ce n'est pas marqué comme tel, nous avons un bug IDE étrange.

    ShowDice(); 
    delete MYbitmap; 
    int a = 0; // try to add this dummy line and debug again 
    
  2. Peut-être ShowDice(); déclenche une exception? Alors vous n'atteindrez jamais cette ligne. Essayez d'attraper toutes les exceptions et imprimez le résultat. Si tel est le cas, votre code devrait similaire à:

    try { 
        ShowDice(); 
    } 
    catch(...) { // catch all exceptions and do something with them 
        delete MYbitmap; 
        throw; 
    } 
    delete MYbitmap; 
    
+0

Dans l'exemple 2, Mybitmap n'est pas supprimé si ShowDice() n'est pas lancé. – Bill

+0

Non, aucune exception n'est possible dans ShowDice(); – DelphiProgrammer

+0

Bill, merci du commentaire. J'ai réparé ça. Pitty, il n'y a pas de standard pour "enfin". MLB: Comment as-tu un comportement avec "int a = 0"? Aussi saute-t-il? –

3

Depuis l'appel ShowDice(); ne dépend pas de la variable MYbitmap, le compilateur est libre de réordonner les deux dernières déclarations. Cela peut expliquer pourquoi vous ne "frappez" pas la ligne dans le débogueur. Désactivez optimisation et réessayez.

De plus, puis-je suggérer d'utiliser un wrapper RAII comme std::auto_ptr ou boost::scoped_ptr au lieu de la gestion manuelle de la mémoire?

0

Vous pouvez essayer:

void RotateDice() 
{ 
    Graphics::TBitmap MYbitmap; 
    ... 

    ShowDice(); 
    // No delete needed 
}; 

Création d'un TBitmap sur la pile signifie que C++ est forcé de le supprimer correctement, même si ShowDice() renvoie une exception.

Est-ce que cela fonctionne avec C++ Builder 6?

+0

Non, TBitmap est une classe VCL (qui ne peut pas être créée sur la pile en raison de l'interopérabilité Delphi) –

+0

Cela ressemble à une déclaration d'une fonction nommée MYbitmap qui prend void et retourne un TBitmap. – bk1e

+0

@ bk1e: Désolé, corrigé. – quamrana

1

Avez-vous activé l'optimisation lors de la compilation? L'optimisation a un moyen de rendre le code très compliqué à exécuter sous un débogueur. Essayez de faire une recompilation complète avec des informations de débogage et l'optimisation complètement désactivée, tout comme un test.

0

compilateur C++ Builder 6 avait un bug, se montrant rarement lorsque vous utilisez ces constructions:

1)

if(condition) 
{ 
    <somecode> 
    break; 
} 

2)

if(condition) 
{ 
    <somecode> 
    continue; 
} 

3)

if(condition) 
{ 
    <somecode> 
    goto label; 
} 

Ici, "somecod e "va toujours être ignoré ou toujours courir sans tenir compte du résultat de l'évaluation de l'état. Le problème est résolu lorsque vous supprimez "continuer", "casser" ou "goto". Il semble que l'instruction switch avec une pause pourrait aussi avoir une telle "fonctionnalité". Essayez de changer le code avant la ligne glitched ainsi:

if(rn == 1) 
{ 
     //... 
} 
    //... other cases... 
else if(rn == ...) 
{ 
    //... 
} 
ShowDice(); //it's a function to show the dice 
delete MYbitmap; //works? 
+0

pouvez-vous afficher un exemple de code complet minimal qui illustre ce bogue dont vous parlez? Je ne me souviens pas avoir déjà rencontré ce bug sur CBuilder6. – greatwolf

+0

@Victor T. Malheureusement, je n'ai pas un tel exemple. Je l'ai rencontré quelques fois avant au moins bcb6 update4 et je ne pouvais pas le reproduire dans un petit échantillon. Le code de l'assembleur a montré qu'il y avait un saut inconditionnel de «si» juste après l'évaluation de l'état. Nasty bug, ça m'a forcé à écrire dans un style de programmation clair et structuré pendant un moment) – Alsk

Questions connexes