C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Очень простая вещ., по языку программирования
sim
Отправлено: 09.03.2004, 21:02


Дежурный стрелочник

Группа: Участник
Сообщений: 39



Такая простая вещ.
if()
{ goto m1;
}
esle
{
}
m1:


Почему иногда если программа большая при компиляции выдается сообщени что не могу откомпелировать goto. У в асемб. джамп есть ближний а есть дальний. А что goto это только ближний джамп?
Pirs
Отправлено: 09.03.2004, 21:14


Дежурный стрелочник

Группа: Участник
Сообщений: 39



Приведи дословно(по-английски) текст ошибки которую выдает компилятор
Георгий
Отправлено: 09.03.2004, 22:13


Почетный железнодорожник

Группа: Модератор
Сообщений: 874



проверил вот так:
CODE
int i=0;
goto end;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
end:


с jmp всё в порядке — если можно использовать ближний, то будет ближний, а если нужен дальний, то будет дальний.

goto не работает вот в таком случае:
CODE
goto l;
AnsiString str;
l:
здесь пропускается инициализация локальной переменной и т.к. её деструктор надо вызывать пра выходе из области видимости, то компилятор отказывается генерировать код.
решение можкт быть таким:
CODE
goto l;
{
AnsiString str;
}
l:


PS. т.к. текст сообщения не был приведён, то всё выше сказанное всего лишь попытки угадать что же у вас случилось.

это похоже самый длинный из моих постов smile.gif

Отредактировано Георгий — 09/03/2004, 23:20
olegenty
Отправлено: 10.03.2004, 08:07


Ветеран

Группа: Модератор
Сообщений: 2412



не представляю такого куска кода, где оператор goto был бы необходим...
Gedeon
Отправлено: 10.03.2004, 09:30


Ветеран

Группа: Модератор
Сообщений: 1742



QUOTE (olegenty @ 10/03/2004, 09:09)
не представляю такого куска кода, где оператор goto был бы необходим...

Совершенно согласен, без него и код красивее и запариться намного меньше шансов. Поэтому лучше все таки как-то переделать код для избежания этого оператора.
trigger
Отправлено: 10.03.2004, 10:02


Не зарегистрирован







не согласен! оператор goto часто бывает более удобным в использованиии. упрощает чтение листинга, и как-то логичнее компилируются в jmp ... имхо конечно smile.gif
так что не смотря на рекомендации во всех книжках по С "не использовать goto" я считаю, не следут его бояться ... smile.gif
olegenty
Отправлено: 10.03.2004, 10:36


Ветеран

Группа: Модератор
Сообщений: 2412



я и не боюсь, но считаю switch и if более соответствующими описанию алгоритма. стоит представить алгоритм в виде блок-схемы, и goto становится не нужен. ну а уж задумываться, как там компилятор единично преобразует goto в jmp... — по моему это оптимизация на пустом месте. от единичной простой инструкции ничего быстрее работать не будет. ну а уж если действительно нужна скорость (в цикле), то и весь кусок можно на асме написать. хоть уджампайся.
olegenty
Отправлено: 10.03.2004, 10:39


Ветеран

Группа: Модератор
Сообщений: 2412



да и к классовому программированию привык. и стараюсь настолько подробно дифференцировать код, чтобы каждый единичный метод был прост и краток. и получается. за последние несколько лет не было необходимости в goto ни разу.
sim
Отправлено: 11.03.2004, 10:08


Дежурный стрелочник

Группа: Участник
Сообщений: 39



Ошибку компилятора сегодня вечером напишу.
Оператор goto я использовал в следующем случаи:

Да, словами это не расказать, вечером выложу исходник...
sim
Отправлено: 11.03.2004, 22:09


Дежурный стрелочник

Группа: Участник
Сообщений: 39



Не удалось востановить ошибку. Программка работает как заколдованная. Чудеса. Да и только. Но если выловлю, обязательно выложу.
trigger
Отправлено: 12.03.2004, 11:45


Не зарегистрирован







то. что прога то работает, то нет — это нормально ...
просто луна вошла в др. фазу ... если вас это раздражает, советую пляски с бубном ... только бубен должен быть сертифицирован от MS

что касается оператора goto, то я не предлагал создавать циклы на нем (в стиле циклов на asm'е) или использовать как-то взамен if ...
я вижу, например, такую область применения для goto:
- наличие большого количества вложенных {блоков операторов} и когда нет возможности тривиально описать условия выхода из каждого из них ...
- или наоборот. когда все очень просто. например форма записывающая данные в таблицу. алгоритм — просто линейный. т.е. последовательно выполняются проверки значений для каждого поля. и только в случае успешного прохождения будет осуществлена запись. а при возникновении какой-либо ошибки — goto из данной функции...
Asher
Отправлено: 12.03.2004, 14:20


Мастер участка

Группа: Модератор
Сообщений: 550



Привет.
QUOTE
а при возникновении какой-либо ошибки — goto из данной функции...

а return использовать не судьба?
и таку штуку как break никто не отменял.

Проблема GoTo (это лично мое IMHO ) в том, что невозможно, в общем случае, определить состояние зависимых переменных в точке прихода. Меняли вы их в этом месте, или в другом, или еще ХЗ где.
Использование GoTo — это просто плохое представление работы алгоритма.
sim
Отправлено: 12.03.2004, 23:39


Дежурный стрелочник

Группа: Участник
Сообщений: 39



Загадка. Вчера как не пробывал- работает. Итак работает и сяк работает. А сегодна не делал ни каких изменений и не компелируется. Вот она ошибка попалась!

[C++ Error] Unit1.cpp(36): E2203 Goto bypasses initialization of a local variable.

А вот часть исходника. !!!!!!!- помечено место ошибки.


void __fastcall TForm1::Button1Click(TObject *Sender)
{
//--------------Подготовка---------------
int iDisk=getdisk();
iDisk++;
int iSize=(DiskFree(iDisk)/1048576); //размер диска в мегобайтах
if(iSize<51) //иначе выходим сообщая об этом
{Application->MessageBox("Закончилось свободное место на диске.","Сообщение",MB_ICONSTOP);
goto m1;
}
bool bDir=DirectoryExists("Zip");
if(bDir==false)
{CreateDir("Zip");
goto m1; //!!!!!!!!!!!!!!!Вот сдесь ругается!!!!!!!!!!!!!!!
}

extern AnsiString aDate; //----получаем текущую дату 030904
//--------------Подготовка---------------
int TbCount=Table1->RecordCount;
Table1->First();
for(int i=0;i {
//Label1->Caption=i;
AnsiString aTFileWr=Table1->FieldByName("FileName")->AsString;
AnsiString aTFileRd=Table1->FieldByName("Path")->AsString; // если=1 то 1 раз

AnsiString aFilePathWrite=AnsiString("Zip\\")+AnsiString(aTFileWr)+AnsiString(aDate)+AnsiString(".zip");

ZipForge1->FileName=aFilePathWrite; //--создаем
ZipForge1->OpenArchive(fmCreate);
ZipForge1->BaseDir=aTFileRd; //--берем из

ZipForge1->Options->StorePath=spRelativePath;
ZipForge1->Options->Recurse=false; //не учитывая дерикторий
ZipForge1->AddFiles("*.dbf");
ZipForge1->AddFiles("1cv7.dd");
ZipForge1->AddFiles("1cv7.md");
ZipForge1->AddFiles("1cv7.ord");
ZipForge1->AddFiles("1cv7.spl");
ZipForge1->Options->Recurse=true; //с учетом директорий
ZipForge1->AddFiles("usrdef\\users.usr");

ZipForge1->CloseArchive();
Table1->Next();
}
Label1->Caption="OK";

//else
//{Application->MessageBox("Закончилось свободное место на диске.","Сообщение",MB_ICONSTOP);
//}
m1:
}


Кстати "а при возникновении какой-либо ошибки — goto из данной функции..." именно так я и пытался использовать оператор. Но когда он не заработал, пришлось вложить друг в друга условия. Или есть еще вариант выделить отдельную подпрограмму.
Asher
Отправлено: 13.03.2004, 11:30


Мастер участка

Группа: Модератор
Сообщений: 550



Привет.
Этим goto m1; ты просто выходишь из подпрограммы.
Выкинь его и забудь. Вместо него напиши return;

ичто это за
QUOTE
for(int i=0;i {


Отредактировано Asher — 13/03/2004, 14:06
sim
Отправлено: 15.03.2004, 10:04


Дежурный стрелочник

Группа: Участник
Сообщений: 39



for(int i=0;i {

Спасибо исправлю. А на счет ошибки не, не понятно из-за чего?

Вернуться в Вопросы программирования в C++Builder