Почему компилятор не компилирует строку в C ++ Builder? - PullRequest
0 голосов
/ 08 февраля 2010

Я программировал приложение на C ++ Builder 6 и столкнулся с этой редкой проблемой:

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!!!!
}

В строке «ShowDice ()» компилятор переходит в финал метода RotateDice (), он не «видит» строку «delete MYbitmap». Когда я компилирую программу, каждая скомпилированная строка показывает маленькую синюю точку в левой части, но эта строка не показывает синюю точку ... это похоже на то, что компилятор не "видит" строку кода. Что происходит с этим ????

Примечание. Несколько дней назад я писал программу на Delphi, и мне посоветовали решить эту проблемную проблему. Что-то подобное случилось со мной в Delphi 7 ... Итак, что за проблема с этим?

Мне очень жаль моего английского. Я с Кубы.

Ответы [ 5 ]

3 голосов
/ 08 февраля 2010

Поскольку вызов ShowDice(); не зависит от переменной MYbitmap, компилятор может переупорядочить последние два оператора. Это может объяснить, почему вы не «попали» в строку отладчика. Отключите оптимизацию и попробуйте снова.

Кроме того, могу ли я предложить использовать вместо RAII оболочку типа std::auto_ptr или boost::scoped_ptr вместо ручного управления памятью?

2 голосов
/ 08 февраля 2010

Как я понял ваша проблема, когда вы отслеживаете ваше приложение, отладчик «перепрыгивает» строку delete MYbitmap;?

  1. Попробуйте поставить точку останова на этой строке. Если это не помечено как таковое, у нас есть странная ошибка IDE.

    ShowDice();
    delete MYbitmap;
    int a = 0; // try to add this dummy line and debug again
    
  2. Может быть ShowDice(); выдает исключение? Тогда вы никогда не достигнете этой линии. Попробуйте перехватить все исключения и распечатать результат. Если это так, ваш код должен быть похож на:

    try {
       ShowDice();
    }
    catch(...) {  // catch all exceptions and do something with them
       delete MYbitmap;
       throw;
    }
    delete MYbitmap;
    
1 голос
/ 08 февраля 2010

Была ли включена оптимизация при компиляции? Оптимизация имеет способ сделать код, который очень запутанным для выполнения под отладчиком. Попробуйте выполнить полную перекомпиляцию с отладочной информацией и полностью отключенной оптимизацией, просто как тест.

0 голосов
/ 14 мая 2010

В компиляторе C ++ Builder 6 была ошибка, которая редко проявлялась при использовании этих конструкций:

1)

if(condition)
{
    <somecode>
    break;
}

2)

if(condition)
{
    <somecode>
    continue;
}

3)

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

Здесь «somecode» будет всегда пропускаться или выполняться всегда, независимо от результата оценки условия. Проблема решается, когда вы удаляете «продолжить», «перерыв» или «перейти». Кажется, что оператор switch с разрывом также может иметь такую ​​«особенность». Попробуйте изменить код до слитной строки следующим образом:

if(rn == 1)
{
        //...
}
   //...  other cases...
else if(rn == ...)
{
   //... 
}
ShowDice();  //it's a function to show the dice
delete MYbitmap;   //works?
0 голосов
/ 08 февраля 2010

Вы можете попробовать:

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

  ShowDice();
  // No delete needed
};

Создание TBitmap в стеке означает, что C ++ вынужден удалить его должным образом, даже если ShowDice () выдает исключение.

Работает ли это с C ++ Builder 6?

...