Текущий архив: 2004.09.12;
Скачать: CL | DM;
Вниз
Нужно ли бороться с хинтами и ворнингами - 2 Найти похожие ветки
← →
Rouse_ © (2004-08-10 23:01) [40]> Если компилятор построит цикл по регистру, значение I после
> выхода из цикла может быть любым.
В смысле ты имеешь ввиду если цикл пройдет до конца и условие не выполнится ни одного раза (не сработает Break)?
← →
Piter © (2004-08-10 23:05) [41]Юрий Зотов © (10.08.04 22:19) [27]
Используя счетчик цикла вне цикла, Вы заставляете компилятор
Юрий! Ну зачем ко мне обращаться на вы?! Даже не на вы, а на Вы!
А вообще интересно, спасибо. Не знал.
Sergey Masloff (10.08.04 22:41) [32]
I := ... <<== ЭТОГО не было. То есть именно работа с тем что там после цикла осталось
... // дальше работаем с I
то есть, сразу работа со значением I? Это, конечно, другое дело совсем, это беспредел.
Но я вот что не понимаю. Если было просто забыто вновь инициализировать переменную - то как это все правильно работает? (ты говорил, что работает то все верно).
P.S. Если не ошибаюсь компилятор должен выдать предупреждение что-то типа неизвестного значения локальной переменной после выхода из цикла...
← →
Piter © (2004-08-10 23:07) [42]Sergey Masloff (10.08.04 22:52) [36]
но вобщем приемный акт им подписали да и использовалась программа все это время. С сегодняшнего дня правда не используется
неужели так сложно было просто хотя бы окинуть код взглядом, это же все увидеть можно за минуту. Тем более вы ж деньги, видимо, платили. И немалые...
← →
Sergey Masloff (2004-08-10 23:10) [43]Piter © (10.08.04 23:05) [41]
>Если не ошибаюсь компилятор должен
Не ошибаешься. Должен и выдавал. Только суперпрограммисты ж их не читают ;-)
>Но я вот что не понимаю. Если было просто забыто вновь >инициализировать переменную - то как это все правильно работает?
Да не забыто. Там на этом логика строится. То есть так и задумано. А как работало? Ну, писалось в лог не то сообщение (которое по индексу бралось). Ну, еще подобного рода фигня вылезала. "Основная" функциональность обеспечивалась. В какой-то мере ;-)
← →
Юрий Зотов © (2004-08-10 23:12) [44]> Rouse_ © (10.08.04 23:01) [40]
Нет, не это. Если компилятор построил цикл по регистру, то, когда программа гонит цикл, его счетчик хранится не в памяти, а в регистре (например, в ECX). После выхода из цикла этот регистр используется уже совсем для другого и содержит совешенно другое значение, никак не связанное со счетчиком. А программа обращается к переменной I, которая хранится уже в памяти и тоже содержит какое-то значение, со счетчиком никак не связанное. В частности, если оно не было проинициализировано, то там будет любой случайный мусор.
Коротко это звучит так - значение счетчика цикла после выхода из цикла не определено. То есть, оно может быть любым - о чем и предупреждает компилятор.
← →
GuAV © (2004-08-10 23:12) [45]
> В смысле ты имеешь ввиду если цикл пройдет до конца и условие
> не выполнится ни одного раза (не сработает Break)?
имхо если пусть Break сработал. но в цикле использована "переменная" регистр. а под повторное и будет или другая "переменная" регистр, или если даже место в стеке под эту выделят, в цикле её все равно юзать не будут
for + Ctrl+Alt+C
← →
Sergey Masloff (2004-08-10 23:13) [46]Piter © (10.08.04 23:07) [42]
>неужели так сложно было просто хотя бы окинуть код взглядом, >это же все увидеть можно за минуту.
А чего я смотреть-то буду? Своих дел чтоли нет? Не я заказывал не я принимал. Как только ко мне попало я посмотрел.
>Тем более вы ж деньги, >видимо, платили. И немалые...
Ну насчет этого не знаю. Малые там или не малые - эту бухгалтерия пусть считает. Не моего ума дела. ИМХО за такое еще с них надо было денег взять ;-)
← →
Rouse_ © (2004-08-10 23:16) [47]> [44] Юрий Зотов © (10.08.04 23:12)
Погоди, если я не ошибаюсь таким образом компилятор действует когда внутри цикла нет обращения к переменой - счетчику, но вот если к I всеже обращаются, то все работает нормально. Это кстати и ответ на вопрос многих, мол почему у меня цикл начитается не с начала до конца а с конца до начала (да потомучто так быстрее)...
← →
GuAV © (2004-08-10 23:20) [48]
> таким образом компилятор действует когда внутри цикла нет
> обращения к переменой
И когда есть ему часто бывает обращатся к ECX удобнее чем к "памяти"
← →
Rouse_ © (2004-08-10 23:23) [49]> [48] GuAV © (10.08.04 23:20)
Хм... поэксперементирую, хотя и не замечал какогото странного его поведения
← →
Cobalt © (2004-08-10 23:26) [50]Там, наверное, ещё и оптимизация включена?
← →
GuAV © (2004-08-10 23:30) [51]procedure TForm1.FormCreate(Sender: TObject);
var S:string; I: Integer;
begin
SetLength(S,10);
for I:=10 downto 0 do S[I]:="G" // тута ставь бряку - EBX считает
end;
← →
Sergey Masloff (2004-08-10 23:38) [52]хинты... варнинги... самое главное забыл. У меня сегодня младший пошел. Ну в смысле впервые своими ногами без посторонней помощи ;-) Вот так.
← →
Ihor Osov'yak © (2004-08-10 23:50) [53]2 [52] Sergey Masloff (10.08.04 23:38)
Поздравляю. Это событие. А хинты и варнинги - действительно, ну их.. Как говорится - думающему и так понятно, а не очень думающему доказывать... В общем-то есть более полезные занятия.
← →
Piter © (2004-08-10 23:57) [54]Rouse_ © (10.08.04 23:16) [47]
таким образом компилятор действует когда внутри цикла нет обращения к переменой - счетчику, но вот если к I всеже обращаются, то все работает нормально. Это кстати и ответ на вопрос многих, мол почему у меня цикл начитается не с начала до конца а с конца до начала
непонятно. Вообще-то компилятор строит цикл задом наперед даже если в цикле есть обращения к счетчику цикла - если я тебя правильно понял, то ты не прав :)
← →
GuAV © (2004-08-11 00:46) [55]
> Вообще-то компилятор строит цикл задом наперед даже если
> в цикле есть обращения к счетчику цикла - если я тебя правильно
> понял, то ты не прав :)
Кажись Rouse_ имел ввиду, что если есть обращения к счетчику, то компилятор _не_ перестроит цикл задом наперёд, потому лучше самому задом наперед построить...
← →
Piter © (2004-08-11 00:52) [56]GuAV © (11.08.04 0:46) [55]
Кажись Rouse_ имел ввиду, что если есть обращения к счетчику, то компилятор _не_ перестроит цикл задом наперёд
так ведь я как раз о том и говорю, что перестроит.
И если мы его правильно понимает - то в данном пункте он не прав.
← →
Zlodey (2004-08-11 02:07) [57]я не понимаю в чём здесь варнинг:
if (edtNOAnsh.Text="")
or (StrToInt(edtNOAnsh.Text)>High(Longint)) //ругается здесь
or (StrToInt(edtNOAnsh.Text)=0) then flag:=flag+1; //не введён номер аншлага
Пишет Comparsion always evaluate to False
← →
Piter © (2004-08-11 02:33) [58]Zlodey (11.08.04 2:07) [57]
Хех, а почему бы компиляторы не ругаться? :)
У тебя одно из условий:
StrToInt(edtNOAnsh.Text)>High(Longint)
High(Longint) это константа=2147483647
StrToInt возвращает число типа Integer. То есть, МАКСИМУМ что оно может вернуть, это теже самые 2147483647
А как 2147483647 может быть больше чем 2147483647?
То есть, это условие ВСЕГДА ложно. Более того, у тебя там одни OR - поэтому в IF попадет ВСЕГДА False. То есть, оператор:
flag:=flag+1;
НИКОГДА НЕ БУДЕТ ВЫПОЛНЕН.
Теперь вопрос - ЗАЧЕМ писать эти строки, которые все равно никогда не будут выполнены. Более того, скорее всего эти комманды и компилироваться то не будут.
← →
Aldor_ (2004-08-11 05:43) [59]
> Zlodey (11.08.04 02:07) [57]
> if (edtNOAnsh.Text="")
> or (StrToInt(edtNOAnsh.Text)>High(Longint))
LOOOL, смотрится очень прикольно :))))))))))
Навереное, имелось в видуUnsignedInteger > High(Longint))
, тогда не StrToInt использовать нужно, а Val напрямую.
← →
Кщд © (2004-08-11 06:49) [60]Piter © (11.08.04 02:33) [58]
истина или ложь=истина
← →
Думкин © (2004-08-11 06:55) [61]> [16] Юрий Зотов © (10.08.04 21:23)
> > DiamondShark © (10.08.04 21:11) [6]
> У Вас?
Имелось в виду, что код приведенный работает точно также как и при:
bOK := SomeCond or SomeOtherCond;
← →
Думкин © (2004-08-11 07:07) [62]> Думкин © (11.08.04 06:55)
Беру слова взад. При полной схеме не так. Звиняюсь.
← →
noname_ (2004-08-11 08:23) [63]2 Rouse_ © [37]
> for I := 0 to Len - 1 do
> if Buff[I] = Условие then Break;
> if I < Len then (Выполняем операции с Buff[I])
>
> Довольно нормальный код, или я не так понял и все намного
> запущеней?
Справка Delphi, раздел "For statements":
"After the for statement terminates, the value of counter is undefined."
← →
Rouse_ © (2004-08-11 09:29) [64]> [56] Piter © (11.08.04 00:52)
Где я не прав?procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
for I := 0 to 10 do
Caption := "qwe";
end;
procedure TForm1.Button2Click(Sender: TObject);
var
I: Integer;
begin
for I := 0 to 10 do
if (i mod 2) = 1 then Caption := "qwe";
end;
В жирных местах ставь бряк и смотри что в первом случае счетчик крутится с конца на начало а во втором как и было задумано.
Не понимаю, что тут можно не понять и где я был не прав? :)
← →
Anatoly Podgoretsky © (2004-08-11 09:41) [65]Смотреть надо ассемблерный код, а не значение в отладчике, код все равно может быть в обратном направление, но значение I будет выдаваться правильное, это уже как оптимизатору виднее, а может построить и прямой цикл, на тех же основаниях.
← →
Rouse_ © (2004-08-11 09:49) [66]В асме тоде все нормально. В первом случае DEC во втором INC
← →
Anatoly Podgoretsky © (2004-08-11 10:02) [67]Rouse_ © (11.08.04 09:49) [66]
Есть и другие случаи, я к тому что показания в отладчике могут отличаться от реального направления в коде. В коде может оказаться и два счетчики прямой для индексации и обратный для отсчета, а может быть и такая конструкция High(I)-I для прямой индексации и обратного отчета по I
У меня на сайте есть пару статей по АСМу там немного затрагивают и это.
Не стоит отвлекаться на то как это в коде, лишь бы был правильный результат - иттерация N раз и последовательность индексации если это важно, не всегда оптимизатор понимает необходимость, в твоем примере и второй вариант мог бы быть обратным по отсчету, поскольку не влияет на результат, но оптимизатор этого не понял.
Кодо генератор и оптимизатор работают по шаблонам, особенно первый так как компилятор однопроходный. Это часто видно в коде в виде таких конструкция
Mov [sp], eax
Mov eax, [sp]
← →
Vetek © (2004-08-11 11:10) [68]помогите "избавиться" от хинта "Value assigned to "z1" never used"
код:
procedure SendCmd(Var q:string);
Var z1,z2,z3,z4,z5:integer; p11:string;
Begin
str((Length(q)+8):8,p11);
q:=p11+q;
z1:=0;z2:=0;
z3:=length(q);z4:=length(q);
metka:=gettickcount;
while true do begin
sleep(debugdelay);
buf2s:=z4;
buf2r:=z2;
fillchar(buf2,sizeOf(buf2),0);
if z3>snd then begin
for z5:=0 to snd-1 do
buf2[z5]:=q[z2+z5+1];
z1:=send(S,buf2,snd,0); end else begin
for z5:=0 to z3-1 do
buf2[z5]:=q[z2+z5+1];
z1:=send(S,buf2,z3,0); end;
z2:=z2+z1;
z3:=z3-z1;
if (not(z1>0))then begin
form1.Statusbar1.SimpleText:="ошибка сокета отправки";
sleep(10);
if form1.CheckBox6.Checked then form1.button1.Click;
break;
end;
if (z2>=z4) then break;
end;
buf2s:=0;
buf2r:=0;
End;
эта процедура работает правильно, но этот хинт не даёт мне покоя ...
в коде- S- переменная типа TSocket;
buf2s,buf2r- переменные для контроля состояния отправки.
← →
Григорьев Антон © (2004-08-11 11:13) [69]
> Vetek © (11.08.04 11:10) [68]
> помогите "избавиться" от хинта "Value assigned to "z1" never
> used"
По-хорошему, надо проверять, что вернула функция Send, а то вдруг связи уже нет, а вы всё данные посылаете. Но если вы считаете, что и без проверки обойдётесь, то лучше вызывать Send как процедуру, без использования значения. И Z1:=0 из 6-ой строки тоже выкинуть.
P.S. А имена переменных до жути информативные...
← →
вразлет © (2004-08-11 11:16) [70]Юрий Зотов © (10.08.04 23:12) [44]
> Rouse_ © (10.08.04 23:01) [40]
Нет, не это. Если компилятор построил цикл по регистру, то, когда программа гонит цикл, его счетчик хранится не в памяти, а в регистре (например, в ECX). После выхода из цикла этот регистр используется уже совсем для другого и содержит совешенно другое значение, никак не связанное со счетчиком. А программа обращается к переменной I, которая хранится уже в памяти и тоже содержит какое-то значение, со счетчиком никак не связанное. В частности, если оно не было проинициализировано, то там будет любой случайный мусор.
Коротко это звучит так - значение счетчика цикла после выхода из цикла не определено. То есть, оно может быть любым - о чем и предупреждает компилятор.
Я так понимаю это проблема именно Паскаля?
← →
Anatoly Podgoretsky © (2004-08-11 11:17) [71]Лень форматировать код, а продираться через линейный без оступов с гениальными имена тоже нет желания.
← →
Danilka © (2004-08-11 11:19) [72][70] вразлет © (11.08.04 11:16)
> Я так понимаю это проблема именно Паскаля?
Думаю, разработчика. :)) Да и вообще, это не проблема. :))
← →
Vetek © (2004-08-11 11:23) [73]Григорьев Антон © (11.08.04 11:13) [69]
if (not(z1>0))then begin
form1.Statusbar1.SimpleText:="ошибка сокета отправки";
- проверка на наличие связи
- я эту процедуру использую во всех своих "сокетных" программах :))
- да, надо бужет изменить имена переменных ...
> И Z1:=0 из 6-ой строки тоже выкинуть.
- инициализировать не обязательно ?
← →
вразлет © (2004-08-11 11:23) [74]Danilka ©
Это понятно)
← →
Sandman25 © (2004-08-11 11:23) [75]if (not(z1>0))
->
if z1 <= 0
← →
Григорьев Антон © (2004-08-11 11:33) [76]
> Vetek © (11.08.04 11:23) [73]
> Григорьев Антон © (11.08.04 11:13) [69]
> if (not(z1>0))then begin
> form1.Statusbar1.SimpleText:="ошибка сокета отправки";
> - проверка на наличие связи
> - я эту процедуру использую во всех своих "сокетных" программах
> :))
Прямо классика! Ошибка в 17-ой строке :))) Кроме шуток, в 17-ой строке вызывается z1:=send(...), а потом это значение нигде не используется.
> > И Z1:=0 из 6-ой строки тоже выкинуть.
> - инициализировать не обязательно ?
Так при первом присвоении она и инициализируется.
А вообще, Анатолий Подгорецкий прав. Просить людей разобраться с таким неформатированным кодом - это проявление неуважения, граничащего с хамством. Я замучался искать, какому end"у какой begin соответствует.
← →
Игорь Шевченко © (2004-08-11 11:34) [77]Sergey Masloff (10.08.04 22:52) [36]
> >И это работало?
> Ну вобщем, работало. Ну эпизодически происходили всякие
> побочные эффекты. Типа при запуске на одних и тех же данных
> то отрабатывало то нет, то обращение к памяти по 0 адресу
> но вобщем приемный акт им подписали да и использовалась
> программа все это время.
Про код, это конечно интересно и поучительно :)
Я даже рад, что ты его выкладываешь с критикой :)
> У меня сегодня младший пошел. Ну в смысле впервые своими
> ногами без посторонней помощи ;-)
Поздравляю! Ну их нафиг, хинты и варнинги :))
Rouse_ © (10.08.04 22:54) [37]
> for I := 0 to Len - 1 do
> if Buff[I] = Условие then Break;
> if I < Len then (Выполняем операции с Buff[I])
>
> Довольно нормальный код, или я не так понял и все намного
> запущеней?
>
> ЗЫ: Я сам часто использую повторно переменные типа I после
> их повторной инициализации и только потому, что не вижу
> смысла создавать кучу временных переменных...
И что, компилятор молчит ? Сомневаюсь...
← →
Плохиш © (2004-08-11 11:37) [78]
> Vetek © (11.08.04 11:23) [73]
> - инициализировать не обязательно ?
А смысл, если перед использованием ты ей всё равно новое значение присваиваешь.
PS. кстати см. [71] и ответь на вопрос: Почему ты нас так не уважаешь?
← →
Danilka © (2004-08-11 11:41) [79]
> И что, компилятор молчит ? Сомневаюсь...
Еще как молчит, по-крайней мере на Д5. И по-моему на всех предыдущих версиях тоже молчал.
← →
Vetek © (2004-08-11 11:42) [80]Григорьев Антон © (11.08.04 11:33) [76]
//.. Просить людей разобраться с таким неформатированным кодом - //это проявление неуважения, граничащего с хамством. ...
ок, извините, понял, исправлюсь :)
- просто я всегда писал тока "для себя" - и об именах переменных и о форматировании кода думал в песледнюю очередь - по мне главное - чтобы правильно работало ..
Страницы: 1 2 3 4 вся ветка
Текущий архив: 2004.09.12;
Скачать: CL | DM;
Память: 0.64 MB
Время: 0.034 c