Текущий архив: 2004.08.29;
Скачать: CL | DM;
Вниз
Нужно ли бороться с хинтами и ворнингами? Найти похожие ветки
← →
Григорьев Антон © (2004-08-08 08:47) [0]Вопрос навеян постом [369] Юрия Зотова в ветке http://delphi84.valuehost.ru/cgi-bin/forum.pl?id=1090676641&n=3 (Калькулятор). Там Юрий утверждает, что все хинты и предупреждения компилятора надо вычищать (в смысле, подправлять код так, чтобы их не было). Я с таким подходом не совсем согласен, потому что бывает немало кусков корректного кода, которые компилятору в силу его ограниченности кажутся подозрительными. Вот два примера, которые мне уже глаза намозолили:
procedure ...
var A:TSomeType;
begin
...
if Некторое условие then
begin
// Какие-то действия, в т.ч. инициализация A
end;
// Здесь ещё какие-то действия
if То же самое условие then
begin
// Здесь снова используется A
end;
...
end;
Переменная A используется только внутри первого и второго if"ов. Во втором if"е получаем предупреждение: переменная, возможно, не инициализирована. Но я-то не компилятор, я понимаю, что второй if будет выполнен, только если перед этим был выполнен первый, и переменная всё-таки будет инициализирована. Ну и что мне делать? Вставлять в начало функции бессмысленную инициализацию A произвольным значением? А зачем? Лишний код, лишнее время работы процедуры. Конечно, издержки мизерны, но важен сам принцип.
Другой пример (кусок кода, кстати, из моего калькулятора).
Val(Copy(S,P,255),R,D);
J:=D;
Val(Copy(S,P,J-1),R,D);
Суть здесь вот в чём: в результате предыдущего анализа я знаю, что в строке S начиная с символа с индексом P записано число. А после числа идёт ещё что-то. Первый раз я вызываю Val для того, чтобы определить, на каком символе закнчивается число (его индекс заносится в D). Второй вызов нужен для того, чтобы получить это число. Так вот, на первом вызове получаем хинт: значение, присвоенное R, нигде не используется. А как я могу его использовать, если в документации нет информации о том, какое значение получит R, если строка не представляет собой корректное число. Зачем мне использовать переменную со случайным значением? Можно, конечно, вставить фиктивный код для этого, но опять же, я не компилятор, я понимаю, что здесь всё в порядке.
А если отклюяать хинты и варнинги (хотя бы локально), то можно и в самом деле что-то важно пропустить.
Одним словом, вопрос такой: нужно ли бороться с хинтами и варнингами ценой вставки бесполезного кода, или фиг с ними, пусть живут?
← →
Думкин © (2004-08-08 09:24) [1]
> procedure ...
> var A:TSomeType;
> begin
> ...
> if Некторое условие then
> begin
> // Какие-то действия, в т.ч. инициализация A
> end;
> // Здесь ещё какие-то действия
> if То же самое условие then
> begin
> // Здесь снова используется A
> end;
> ...
> end;
Если выделенное жирным соответствует написанному то, что мешает сделать так:procedure ...
var A:TSomeType;
begin
...
if Некторое условие then
begin
// Какие-то действия, в т.ч. инициализация A
//end;
// Здесь ещё какие-то действия
//if То же самое условие then
begin
// Здесь снова используется A
end;
...
end;
Если все-же условия не эквивалентны, то компилятор прав в том, что предупреждает.
Второе пока не анализировал, но вполне вероятно и там можно что-то нарыть.
Я в Д7 отключаю только 3 предупреждения - которые включили в предверии .Net - а нафига, я не знаю.
Все остальное и варнинги и хинты - включено. Пишу и всегда делаю так, что ни одного варнинга и хинта не имею, сколько бы строчек кода не было.
Кстати, не раз спасало. Потму как по зеленому, нарывался - ошибка, а оказывается компилятор меня вполне честно предупреждал.
Видимо так. Для начала. :)
← →
Ihor Osov'yak © (2004-08-08 10:15) [2]2 [1] Думкин © (08.08.04 09:24)
Комментарий один перед последним begin потерял.
2 Григорьев Антон © (08.08.04 08:47)
Относительно первого примера. Как говорилось не раз, и не одним человеком - хинт, как минимум, намекает на неаккуратность кода, что, и было продемонстрировано Думкиным. А во вторых, Вы бы полностью привели "Некоторое условие" - в вдруг у Вас там или глобальная переменная или поле класса используется. Откуда компилятору знать, однопоточное у Вас приложение, или многопоточное. Хотя компилятор наверное даст предупреждение и для чисто "локального" условия - но догда снова см. [2].
Относительно второго примера. Имхо, снова случай неаккуратного (непрозрачного) кода. Без вашего комментария трудновато понять, что делают эти три строчки. Конечно, если несколько минут подумать... Но согласитесь, что если думать по несколько минут над несколькими тривиальными строчками.. То есть снова имеем случай "как минимум, намекает на неаккуратность кода".. И даже может на то, что калькулятов пишется без теории :-) Но если серьезно - в определенных случаях, второй пример имеет право на жызнь. Только нужно дополнить его локальными директивами подавления соотв. предупреждения и сопроводить соответсвующим комментарием. Чтобы потом не возникало вопросов. Ни у Вас через полгода, ни у того, кому может придется со временем разгребать Ваш код. Это совсем небольшая плата за кучу сохраненного времени и нервов, которое нам порою обеспечивает очередной хинт компилятора. И который мы точно не провороним в случае работы по правилу - "хинтов и варнингов быть не должно"
← →
Думкин © (2004-08-08 11:16) [3]> [2] Ihor Osov"yak © (08.08.04 10:15)
> 2 [1] Думкин © (08.08.04 09:24)
>
> Комментарий один перед последним begin потерял.
Да, запаостив тоже увидел. Но уже не стал править, а оно вылилось бы - в Error. Все-таки стоит прислушаться иногда и к компилятору и к старперам. %)))
← →
Григорьев Антон © (2004-08-08 11:26) [4]
> Думкин © (08.08.04 09:24) [1]
> Если выделенное жирным соответствует написанному то, что
> мешает сделать так:
Мешает то, что в случае, если условие истинно, между первым и вторым if"ом бывает необходимо выполнить какие-то действия, которые так же должны выполняться и в том случае, если условие ложно.
> Ihor Osov"yak © (08.08.04 10:15) [2]
> 2 Григорьев Антон © (08.08.04 08:47)
>
> Относительно первого примера. Как говорилось не раз, и не
> одним человеком - хинт, как минимум, намекает на неаккуратность
> кода, что, и было продемонстрировано Думкиным. А во вторых,
> Вы бы полностью привели "Некоторое условие" - в вдруг у
> Вас там или глобальная переменная или поле класса используется.
> Откуда компилятору знать, однопоточное у Вас приложение,
> или многопоточное. Хотя компилятор наверное даст предупреждение
> и для чисто "локального" условия - но догда снова см. [2].
Как я уже написал выше, пока Думкин это не продемонстрировал. Не всегда всё удаётся запихнуть в один if, иногда в середине нужны какие-то действия, выполняющиеся безусловно. Компилятор, конечно, прав, когда указывает мне на это, но ведь человек умнее компилятора и может понять то, что компилятору просто недоступно. И я просто не хочу вставлять лишний код там, где это не нужно.
> Относительно второго примера. Имхо, снова случай неаккуратного
> (непрозрачного) кода. Без вашего комментария трудновато
> понять, что делают эти три строчки. Конечно, если несколько
> минут подумать... Но согласитесь, что если думать по несколько
> минут над несколькими тривиальными строчками..
Буду крайне благодарен, если вы предложите мне решение аналогичной задачи, столь же короткое и эффективное, но более очевидное. Мне и самому эти строчки не нравятся, но всё, что мне приходит в голову, будет более громоздко. На всякий случай - в строке там не целые числа, а вещественные, т.е. просто пройти по символам и найти первую не-цифру не получится.
← →
Думкин © (2004-08-08 11:41) [5]> [4] Григорьев Антон © (08.08.04 11:26)
> Мешает то, что в случае, если условие истинно, между первым
> и вторым if"ом бывает необходимо выполнить какие-то действия,
> которые так же должны выполняться и в том случае, если условие
> ложно.
....
> недоступно. И я просто не хочу вставлять лишний код там,
> где это не нужно.
Оно понятно. Это также как и ..
1. Return value of function "-----" might be undefined
2. Variable "--" might not have been initialized
Человек очень многое подразумевает. К сожалению, при использовании другими это знание не всегда сразу воспроизводится. И может приводить к жутким глюкам, примеры я думаю были почти у всех. Когда рассматриваешь код, - ага тут он подразумевал это, а тут это, а тот второй этого не заметил, ага - а чтот мне теперь делать - видимо рефакторинг по Российски?
Но все-таки
И я просто не хочу вставлять лишний код там, где это не нужно.
это для быстрого и на уровне кратких утилит, либо о жестком документировании как и пишет Игорь.
Если я пишу что-то для 3-х мминутного использования, то и не на такое можно бы положить, но уже и тут привычка, хотя не без греха, каюсь, но последнее время - даже не помню.
← →
Anatoly Podgoretsky © (2004-08-08 11:47) [6]Абсолютно правильные сообщения компилятора, а что делать, так ведь уже давно решил, ну его побоку этот компилятор.
А стоит подумать и сделать перепроектирование.
← →
VID © (2004-08-08 11:59) [7]>>Григорьев Антон © (08.08.04 11:26) [4]
>>На всякий случай - в строке там не целые числа, а вещественные, т.е. просто пройти по символам и найти первую не-цифру не получится.
Вещественное число от целочисленного отличается одной лишь точкой или запятой! Так что не надо драматизировать, не грех и по символьной пройтись по строке S, и проанализировать её.
А как сформировать вещественное число, зная её целую и дробную часть, я думаю ты и сам в курсе ;)
← →
Ihor Osov'yak © (2004-08-08 12:37) [8]2 [7] VID © (08.08.04 11:59)
>отличается одной лишь точкой или запятой!
Если говорить в контексте ф-ци Val - не только. Всякие там $, e, етс.. Ради интетера - см. исходники, модуль system - _ValExt, _ValLong, _ValInt64.. Ох, эти compile magic, или как их там.. Вот, если бы можно было напрямую вызвать _ValExt - не страдал-бы Антон ерундой.
2 [4] Григорьев Антон © (08.08.04 11:26)
немного прелюдии - имхо, "неприятность" с Val спровоцирована не очень уместным желанием разрешить "выбрасывание" знака умножения. Кстати, не задумывались почему даже в довольно терпимых к разного рода вольностям языках, той же си, все же символ умножения указывать обязательно?
По теме. При возникновении такой проблемы я бы еще раз проанализировал постановку задачи, спецификацию. В случае "позно, дядя - закомпосировали" - все же директивы компилятора локальные убивающие один этот варнинг с подробным комментарием. Ну, если было <укр>"час та натхнення"</укр> - может написал-бы процедуру, "более громоздкую" но зато более прозрачную.
Еще. см. [5] и очень подумайте над [6]
← →
VMcL © (2004-08-08 12:58) [9]>>Ihor Osov"yak © (08.08.04 12:37) [8]
>Вот, если бы можно было напрямую вызвать _ValExt...
Выдам страшную тайну:asm
// ...
call System.@ValExt
end;
← →
Ihor Osov'yak © (2004-08-08 13:07) [10]2 [9] VMcL © (08.08.04 12:58)
во, век учись...
и что обидно, похожие вещи в общем-то делал..
← →
DiamondShark © (2004-08-08 14:00) [11]
> Григорьев Антон © (08.08.04 08:47)
> procedure ...
> var A:TSomeType;
> begin
> ...
> if Некторое условие then
> begin
> // Какие-то действия, в т.ч. инициализация A
> end;
> // Здесь ещё какие-то действия
> if То же самое условие then
> begin
> // Здесь снова используется A
> end;
> ...
> end;
procedure ...
procedure Unconditional;
begin
// независимые от условия;
end;
procedure Conditional;
begin
// Какие-то действия
Unconditional;
// Здесь снова
end;
begin
...
if Некторое условие then
Conditional
else
Unconditional
end;
И никаких переменных с аномальным временем жизни.
← →
Aldor. (2004-08-08 14:20) [12]Вот свежий пример, только что вылезло:
function FuncName: Boolean;
begin
Result := False;
...
try
...
finally
...
end;
Result := True;
end;
(выдать True только в случае удачного завершения)
получаем: [Hint] uEngine.pas(193): Value assigned to "FuncNam" never used
Как сделать такой код более грамотным, в голову не приходит, поэтому и пришел сюда за советом (не для того чтобы что-то доказать).
← →
DiamondShark © (2004-08-08 14:26) [13]
> Aldor. (08.08.04 14:20) [12]
Этот код вообще не должен быть функцией.
← →
Aldor. (2004-08-08 14:43) [14]> Этот код вообще не должен быть функцией.
Почему? Функция выполняет свои действия и возвращает True если они все выполнены успешно. Except, насколько я понимаю, это не очень хорошо в данном случае.
← →
Anatoly Podgoretsky © (2004-08-08 14:50) [15]Aldor. (08.08.04 14:20) [12]
Правильно верхнее значение не используется, а в случае ошибки не используется и нижнееResult := True;
finally
← →
Ihor Osov'yaka (2004-08-08 14:54) [16]2 [14] Aldor.
> Почему?
Потому что в случае возникновения исключительной ситуации в месте вызова функции присваивания результата работы функции соотв. перевенной вообще происходить не будет - там уже будет стремительный бег по цепочке секций exception/finally. То есть действительно результаты деятельности
Result := False;
нигде использоваться не будут.
Зы. Протрассируйте небольшой тестовый пример. Либо на ассемблере, либо поставив точку прерывания на изменение переменной, которая получает значение функции.. Если то или то затруднительно - в роли переменной, принимающей значение поставте свойство с методом Set (на входе которй ставим точку прерывания).
← →
VID © (2004-08-08 14:59) [17]function FuncName: Boolean;
begin
try
try
...
Result := True;
except
Result := False;
end;
finally
...
end;
end;
← →
Ihor Osov'yak © (2004-08-08 15:11) [18]2 [17] VID ©
А это уже совсем другие пироги. Корректные в плане возвращения результата.. А вот относительно финишного файнели и отсутствия троеточия перед первым try нехорошие ассосиации возникают :-).
Зы - приходилось видеть и такой код -
try
mObj := TMyObj.Create;
...
finally
mObj.Free;
end;
и что удручает - не единыжды.. И в общем - не в совсем начинающих..
← →
Aldor. (2004-08-08 15:12) [19]Anatoly Podgoretsky © (08.08.04 14:50) [15]
Result := True;
finally
Да, именно это имелось в виду. И тоже, кстати, варнинг (тот же).
VID © (08.08.04 14:59) [17]
function FuncName: Boolean;
begin
try
try
...
Result := True;
except
Result := False;
end;
finally
...
end;
end;
А хорошо ли здесь юзать except? Я помню советы о том, что использование except нужно минимизировать.
← →
Григорьев Антон © (2004-08-08 15:17) [20]
> VID © (08.08.04 11:59) [7]
> >>Григорьев Антон © (08.08.04 11:26) [4]
> >>На всякий случай - в строке там не целые числа, а вещественные,
> т.е. просто пройти по символам и найти первую не-цифру не
> получится.
>
> Вещественное число от целочисленного отличается одной лишь
> точкой или запятой! Так что не надо драматизировать, не
> грех и по символьной пройтись по строке S, и проанализировать
> её.
Одной только точкой? Ну-ну... Стало быть, 2.56E-28 уже вещественным числом не является?
Впрочем, разбор и такой строки я написал бы без проблем, если б мне надо было. Вопрос-то в другом. Есть код из трёх строчек, который делает то, что мне нужно. Делает вполне корректно и безошибочно. И производительность у него достаточно высока. Единственный его недостаток - по глупости своей компилятор выдаёт на нём хинт. А мне тут предлагают заменить его на код из пары десятков строчек, который вряд ли будет работать быстрее, и всё это только для того, чтобы убрать хинт. А стоит ли овчинка выделки?
> Ihor Osov"yak © (08.08.04 12:37) [8]
> 2 [4] Григорьев Антон © (08.08.04 11:26)
>
> немного прелюдии - имхо, "неприятность" с Val спровоцирована
> не очень уместным желанием разрешить "выбрасывание" знака
> умножения. Кстати, не задумывались почему даже в довольно
> терпимых к разного рода вольностям языках, той же си, все
> же символ умножения указывать обязательно?
А вот щаз возьму и обижусь! :))))) Возмущён до глубины души - приписывать мне такие глупые идеи! :)) Будет время - загляните в ветку "Калькулятор" - именно я больше всех убеждал там GrayFace"а, что писать калькулятор, допускающий умножение без знака, глупо. А задача такая возникает и при выделении чисел из строки "2+2", и беззнаковое умножение тут ни при чём.
> Ну, если было <укр>"час та натхнення"</укр> - может написал-бы
> процедуру, "более громоздкую" но зато более прозрачную.
Да я бы её тоже написал, если б понимал, зачем. Просто я не считаю убирание хинтов из корректно работающего кода самоцелью. А других причин переделывать данный код я не вижу. Вот и интересуюсь: может быть, у других глаза получше?
А что касается прозрачности, то это во многом субъективный критерий. Я вот привык к такому коду, мне он кажется вполне понятным.
Кстати, кому интересно, примеры кода взяты из модуля ExprMake, который можно скачать здесь: http://www.delphikingdom.com/asp/viewitem.asp?catalogid=718
Другая версия того же алгоритма разбора выражения, более простая, но с подробными комментариями, лежит здесь: http://www.delphikingdom.com/treasury/s003.htm#link7
> DiamondShark © (08.08.04 14:00) [11]
Ещё раз прочитайте, что я написал: некоторый код должен выполняться безусловно обязательно между if"ами! В вашем примере я этого не увидел. У меня что-то с глазами?
← →
Piter © (2004-08-08 15:23) [21]Ну насчет подавления ВСЕХ warning и hint"ов - даже сами модули VCL компилируются с предупреждениями. Так что ответ очевиден - борландовцы явно не глупее нас с вами и если считают, что компиляция с warning осуществима - значит, так оно и есть.
Хотя, конечно, я лично стараюсь подавить все высказывания компилятора, зачастую просто раздражают строки снизу, создается какая-то неполноценность продукта :) Даже не знаю как объяснить...
← →
Григорьев Антон © (2004-08-08 15:59) [22]
> Piter © (08.08.04 15:23) [21]
> Хотя, конечно, я лично стараюсь подавить все высказывания
> компилятора, зачастую просто раздражают строки снизу, создается
> какая-то неполноценность продукта :) Даже не знаю как объяснить...
Это ты в точку. Очень раздражают :)) Но пользу они тоже очень часто приносят.
← →
Ihor Osov'yak © (2004-08-08 16:18) [23]2 [20] Григорьев Антон ©
> именно я больше всех убеждал там GrayFace"а,
Прошу извинения :-). Но только по этому пункту..
> и при выделении чисел из строки "2+2", и беззнаковое умножение тут ни при чём.
ну, лично бы я "множители" (используя Вашу же терминологию с http://www.delphikingdom.com/treasury/s003.htm#link7 ) я бы все же по другому выделял.. Но это уже в сторону, мы же флеймим вокруг Val.
Я бы наверное, пожертвовал все же 2-3 строчками, и сделал что-то типа{$HINTS OFF}
function FindPosAfterNumber(const aStr: string): integer;
var
r: extended;
i: integer;
begin
Val(aStr, r, i);
if i = 0 then
result := length(aStr) + 1
else
result := i;
end;
{$HINTS On}
а в случае наличия времени and so on -function FindPosAfterNumber2(const aStr: string): integer;
var
i: integer;
begin
asm
lea edx, i
lea eax, aStr
mov eax, [eax]
call System.@ValExt
end;
if i = 0 then
result := length(aStr) + 1
else
result := i;
end;
В случае испосльзования специализированной процедуры и комментировать особо ничего не нужно..
← →
Ihor Osov'yak © (2004-08-08 16:22) [24]хотя здесь финт if i = 0 then наверное лишний, зависит от контескта..
Ну и i - тоже, можно использовать result, так что реальный код будет компактнее.
← →
имя (2004-08-08 16:26) [25]Удалено модератором
← →
имя (2004-08-08 16:26) [26]Удалено модератором
← →
имя (2004-08-08 16:26) [27]Удалено модератором
← →
имя (2004-08-08 16:26) [28]Удалено модератором
← →
имя (2004-08-08 16:26) [29]Удалено модератором
← →
имя (2004-08-08 16:26) [30]Удалено модератором
← →
имя (2004-08-08 16:26) [31]Удалено модератором
← →
имя (2004-08-08 16:26) [32]Удалено модератором
← →
имя (2004-08-08 16:26) [33]Удалено модератором
← →
имя (2004-08-08 16:26) [34]Удалено модератором
← →
имя (2004-08-08 16:26) [35]Удалено модератором
← →
имя (2004-08-08 16:26) [36]Удалено модератором
← →
имя (2004-08-08 16:27) [37]Удалено модератором
← →
имя (2004-08-08 16:27) [38]Удалено модератором
← →
имя (2004-08-08 16:27) [39]Удалено модератором
← →
имя (2004-08-08 16:27) [40]Удалено модератором
← →
имя (2004-08-08 16:27) [41]Удалено модератором
← →
имя (2004-08-08 16:27) [42]Удалено модератором
← →
имя (2004-08-08 16:27) [43]Удалено модератором
← →
имя (2004-08-08 16:27) [44]Удалено модератором
← →
имя (2004-08-08 16:27) [45]Удалено модератором
← →
имя (2004-08-08 16:27) [46]Удалено модератором
← →
имя (2004-08-08 16:27) [47]Удалено модератором
← →
имя (2004-08-08 16:27) [48]Удалено модератором
← →
имя (2004-08-08 16:27) [49]Удалено модератором
← →
Бином Ньютоныч (2004-08-08 16:47) [50]>[25] - [49]
"Он по-своему несчастный был - дурак!"
(c)В.Высоцкий
← →
VMcL © (2004-08-08 17:06) [51]>>Бином Ньютоныч (08.08.04 16:47) [50]
Не обращай внимания. Похоже, опять атака на форум...
← →
Юрий Зотов © (2004-08-08 18:52) [52]Мое IMHO.
Как я отношусь к хинтам и варнингам? Очень просто - их не должно быть. Ни единого.
И - хотите верьте, хотите нет - но у меня их и правда нет ни единого. За все время программирования - а это уже несколько десятков лет.
Как я этого добиваюсь? Очень просто.
1. Любой хинт или варнинг подвергается разбору. В 99% случаев видим, что компилятор совершенно прав, а не просто так дурку валяет. Соответственно, код видоизменяется так, чтобы сообщение компилятора исчезло, но никаких лишних операций в программе не появилось.
2. Если это не получается и для того, чтобы сообщение исчезло, нужны какие-то ненужные действия (что бывает в 0.1% случаев), то производим более тщательный анализ кода. Если есть абсолютная уверенность, что он действительно на 100% безопасен - отключаем сообщение директивами компилятора, но только ЭТО сообщение и только на ЭТОТ кусок кода ($WARN xxx OFF
и далее$WARN xxx ON
). Если же такой уверенности нет, значит эти действия вовсе не лишние и ДОЛЖНЫ быть выполнены.
Вот и все. При некотором навыке кодинга все это практически не отнимает времени, а программа становится чище и надежнее. И ни один новый хинт/варнинг теперь уже не будет проворонен.
← →
Григорьев Антон © (2004-08-08 18:53) [53]
> Ihor Osov"yak © (08.08.04 16:18) [23]
> В случае испосльзования специализированной процедуры и комментировать
> особо ничего не нужно..
Ну, это кому как :))
Увидев в коде Val, человек может нажать F1 и прочитать, что это за процедура. А вот ValExt в справке не описан, а по исходникам лазить умеют далеко не все (а у тех, кто работает на честно купленной Delphi, исходников может не быть просто из экономии - без них Delphi дешевле). Да и с совместимостью в следующих версиях Delphi могут быть проблемы. Одним словом, вернулись к тому, о чём я говорил: понятность кода - вещь субъективная.
А вообще, если не стремиться получить столь же эффективный код, вопрос "а как ещё можно сделать" мне не очень интересен - я сам могу предложить несколько вариантов. Меня интересует другое: зачем нужно изменять мой код. Только для того, чтобы избавиться от хинта? Не впечетляет меня такая цель. А ничего конкретного против пока не было сказано, только общие рассуждения на тему чистого и грязного кода. Действительно ли полное отсутствие хинтов - абсолютная ценность, цель, которой во что бы то ни стало надо достичь? Я пока не вижу серьёзных аргументов за такой подход.
← →
Юрий Зотов © (2004-08-08 19:07) [54]> Григорьев Антон © (08.08.04 18:53) [53]
> Действительно ли полное отсутствие хинтов - абсолютная ценность, цель, которой во что бы то ни стало надо достичь?
Нет, конечно. Цель другая - не прозевать новые хинты/варнинги, которые уже могут быть действительно опасны.
> Я пока не вижу серьёзных аргументов за такой подход.
Вот один из таких аргументов - время, потраченное на избавление от хинтов/варнингов СРАЗУ же при написании кода пренебрежимо мало по сравнению с временем вылавливания непонятно откуда вдруг взявшегося ПЛАВАЮЩЕГО бага, который ЗАПРОСТО может появиться, если мы прозевали новый хинт/варнинг. То есть, время мы на самом деле ЭКОНОМИМ, а не теряем - плюс повышается надежность программы.
← →
Гаврила © (2004-08-08 20:08) [55]Конечно их не должно быть !
Это даже не обсуждаемо.
Так как, если программист допускает "опечатку" в коде, компилятор в ряде случаев может его поправить хинтом или варнингом. Если их уже 150, программист просто его не заметит.
Если явный случай бестолковости компилятора (такое, увы, бывает), то {$Warinigs OFF}...$Warinigs ON}
сорри, если повторил чью-то мысль
Прав Юра Зотов
Штрафы надо вводить = за хинт 5 уе, за варнинг - 10
← →
Piter © (2004-08-08 21:38) [56]я не понимаю о чем спор? Может кто объяснит?
Все говорят одно и тоже... вы просто решили укрепиться в своей вере? :)
← →
Ihor Osov'yak © (2004-08-09 00:52) [57]2 [56] Piter © (08.08.04 21:38)
> я не понимаю о чем спор? Может кто объяснит?
флейма ради, флейма :-)
2 [53] Григорьев Антон © (08.08.04 18:53)
> А вот ValExt в справке не описан ...
ну я ж говорил, что в случае наличия времени и ...
Реально, конечно, был бы написан вариант 1.
> а у тех, кто работает на честно купленной Delphi, исходников может не быть просто из экономии
Кстати, минимальный вариант делфи, на котором можна писать софт с бизнес-целью - professional. А он уже идет с исходниками. в тч. system.pas.
а остальное уже передо мною сказали.
← →
Григорьев Антон © (2004-08-09 07:56) [58]
> Юрий Зотов © (08.08.04 18:52) [52]
> 2. Если это не получается и для того, чтобы сообщение исчезло,
> нужны какие-то ненужные действия (что бывает в 0.1% случаев),
> то производим более тщательный анализ кода. Если есть абсолютная
> уверенность, что он действительно на 100% безопасен - отключаем
> сообщение директивами компилятора, но только ЭТО сообщение
> и только на ЭТОТ кусок кода ($WARN xxx OFF и далее $WARN
> xxx ON). Если же такой уверенности нет, значит эти действия
> вовсе не лишние и ДОЛЖНЫ быть выполнены.
А как бы ты поступил в случае с двумя if"ами и промежуточным безусловным кодом? Если тупо отключить предупреждение на весь второй if, то можно не получить сообщение о том, что не инициализирована какая-то другая переменная, а это уже будет плохо.
> Piter © (08.08.04 21:38) [56]
> я не понимаю о чем спор? Может кто объяснит?
Лично я ни с кем не спорю. Просто я понял, что на эту проблему существует точка зрения, отличная от моей. И теперь я хочу до конца понять чужую точку зрения, чтобы сделать для себя выводы.
← →
Думкин © (2004-08-09 08:03) [59]
if a then b;
c;
if a then d;
if a then begin
b;
c;
d
end
else c;
То есть второе не устраивает? Об этом?
← →
Григорьев Антон © (2004-08-09 08:24) [60]
> Думкин © (09.08.04 08:03) [59]
> То есть второе не устраивает? Об этом?
Да, не устраивает. По двум причинам.
1. "с" может быть достаточно большим, и его дублирование приведёт к неоправданному разбуханию кода. Уж лучше тогда добавить перед if"ами инициализацию проблемной переменной фиктивным значением.
2. Если придётся переделывать "с", то надо будет вносить изменения в два куска кода и строго следить за их идентичностью.
Если вынести "с" в отдельную процедуру, то вторая проблема снимается, а первая становится намного менее острой. Но тогда можно получить другую проблему: в этой процедуре окажутся объединены вырванные из контекста разнородные действия, и ясность кода от этого уменьшится.
← →
Sha © (2004-08-09 09:52) [61]> Вот два примера, которые мне уже глаза намозолили...
Одного этого достаточно, чтобы поставить пару лишних операторов.
На анализ того, откуда эти варнинги возникли, к чему могут привести и т.п. ты в сумме потратишь больше времени, чем будет сэкономлено твоей программой за все время ее жизни у всех пользователей. По-моему, твое время для тебя должно быть дороже.
← →
Гаврила © (2004-08-09 10:03) [62]
> "с" может быть достаточно большим, и его дублирование приведёт
> к неоправданному разбуханию кода
Каки проблемы ? Вынести в приватный метод, или во внутреннюю процедуру(что лучше)
← →
Sandman25 © (2004-08-09 10:17) [63]var
s: string;
i: integer;
c: integer;
begin
s := edit1.text;
Val(s, i, c);
if c = 0 then
caption := s;
end;
Выдается
Value assigned to "i" never used
Ну и как это исправлять? Писать Caption := IntToStr(i)?
← →
Думкин © (2004-08-09 10:22) [64]
> [63] Sandman25 © (09.08.04 10:17)
Видимо, это связано с тем, что Val предназначена для:
Converts a string to a numeric representation.
А не для проверки. Или как?
← →
Danilka © (2004-08-09 10:23) [65][63] Sandman25 © (09.08.04 10:17)
Какая версия дельфи?
В 7 (а может и 6) есть ф-я, которая проверяет число/не число.
К сожалению, нет сейчас под рукой, немогу сказать точно какая, по-моему в StrUtils лежит.
А так, в общий для всех модулей модуль выкладывал самописную такую ф-ю, которая проверяла, в данном случае был-бы просто ее вызов. :))
← →
Sandman25 © (2004-08-09 10:28) [66][64] Думкин © (09.08.04 10:22)
Ну и как проверять? Через StrToIntDef или TryStrToInt? И зачем замедлять?
[65] Danilka © (09.08.04 10:23)
3, 4 и 6 :)
← →
Mystic © (2004-08-09 11:08) [67]У меня условный рефлекс --- как только в программе появляется подсказки или предупреждения --- компиляция прекращается. Да, иногда предупреждения бывают лишними (часто в алгоритмических задачах). В этом случае я либо добавляю строку в коментарием Kill warning
const
NEVER_USED_VALUE = $FFFFFFFF;
begin
A := NEVER_USED_VALUE; // Kill warning
if Condition then
A := Random(5);
DoSomething;
if Condition then
begin
Assert(A <> NEVER_USED_VALUE);
ShowMessage(IntToStr(A));
end;
Падение производительности из-за лишнего присваивания меня абсолютно не беспокоит. А когда беспокоит --- просто перепишу фрагмент на ассемблере --- и производительность, и отсуствие предупреждений :)
Кстати, код
Val(Copy(S,P,255),R,D);
J:=D;
Val(Copy(S,P,J-1),R,D);
тоже не является самым оптимальным решением, но вполне рабочим. А если переписать его как:function MyVal(S: string; P: Integer): Extended;
var
ErrSymbol: Integer;
begin
Val(Copy(S,P,Length(S)), Result, ErrSymbol);
if ErrSymbol <> 0 then
Val(Copy(S, P, ErrSymbol-1), Result, Errsymbol);
end;
то и от предупреждения избавляемся, и от повторного разбора в случае, если строка заканчивается числом :) Ну а если есть время, то можно и конечный автомат написать, а еще лучше прикрутить LEX и избавится от проблем ручного лексического анализа.
Кстати, сколько раз исходники от Borland не компилировал, предупреждений и подсказок не наблюдалось :)
← →
Думкин © (2004-08-09 11:23) [68]> [66] Sandman25 © (09.08.04 10:28)
> [64] Думкин © (09.08.04 10:22)
> Ну и как проверять? Через StrToIntDef или TryStrToInt? И
> зачем замедлять?
Мне кажется, что в данном случае проблема не компилятора, а библиотеки.
Потму что функция предназначена для того чтобы конвертировать, а не проверять. А то что ее используют не по назаначению - компилятор ни при чем.
А как проверять? Ну видимо как и писалось - вставить локальные выключения варнингов или написать свое.
← →
Prohodil Mimo © (2004-08-09 11:36) [69]Выставляете игнор варнинга на определённые строки и называете это "ни одного варнинга". Если варнинг в игноре - это не значит, что его нет.
Меня тоже добивает один варнинг:
у меня есть глобальная переменная "счётчик", которую использую в разных процедурах, и Дельфя мне постоянно кричит, что переменная должна быть локальной. Я понимаю, что могу в одном цыкле вызвать другую процедуру в которой цыкл с той же переменной, но у меня такого нет. Компилятор мог бы проверять на подобные ситуации и не паниковать каждый раз.
← →
Anatoly Podgoretsky © (2004-08-09 11:38) [70]Prohodil Mimo © (09.08.04 11:36) [69]
А зачем тебе глобальная переменная цикла?
← →
VMcL © (2004-08-09 11:41) [71]>>Prohodil Mimo © (09.08.04 11:36) [69]
Себе же делаешь хуже (точнее своей программе). При включенной оптимизации, если переменная, локальная, под неё память может вообще не выделяться - она будет в регистре. А если глобальная, то память компилятору придется выделить.
← →
Sandman25 © (2004-08-09 11:43) [72][71] VMcL © (09.08.04 11:41)
+ размер экзешника увеличивается
← →
Prohodil Mimo © (2004-08-09 11:43) [73][70] Anatoly Podgoretsky, а чтобы не создавалась каждый раз при запуске процедур и функций.
Переменные используемые в более 50% процедур обычно выношу в глобальные. А зачем их каждый раз создавать\уничтожать, если всё равно понадобится?
← →
Думкин © (2004-08-09 11:44) [74]> [69] Prohodil Mimo © (09.08.04 11:36)
> Выставляете игнор варнинга на определённые строки и называете это "ни одного варнинга". Если варнинг в игноре - это не значит, что его нет.
Кто выставляет и говорит?
← →
Sandman25 © (2004-08-09 11:44) [75][73] Prohodil Mimo © (09.08.04 11:43)
Скачайте эксперт Castalia, он позволяет объявлять переменные прямо в том месте, где они используются.
← →
Думкин © (2004-08-09 11:45) [76]> [73] Prohodil Mimo © (09.08.04 11:43)
Ну если я буду присутствовать при собеседовании - тебе работа не светит.
← →
Anatoly Podgoretsky © (2004-08-09 11:47) [77]Prohodil Mimo © (09.08.04 11:43) [73]
А ее создавать не надо, она создается на этапе компиляции и автоматически размещается на стеке.
← →
Anatoly Podgoretsky © (2004-08-09 11:47) [78]Это очень серезное предпреждение!
← →
Sandman25 © (2004-08-09 11:47) [79][76] Думкин © (09.08.04 11:45)
Самое интересное, что он может оказаться прав. Например, в том случае, если речь идет об объектах с большим временем создания/инициализации. В данном конкретном случае со счетчиками я с тобой согласен, конечно.
← →
Prohodil Mimo © (2004-08-09 12:04) [80][74] Думкин, ну хотя бы [52] 2.
[76], глобальных переменных не должно быть?
А если 10 процедур по обработке таблицы, к примеру обработка СтрингГрида, перемещение по строкам, колонкам. В каждой процедуре держать эти переменные?
Каждая процедура может вызывать функции, которые используют текущие состояния этих переменных. зачем в них передавать значения, если можно объявить их глобально? Чем это плохо? не тратится время проца. К тому же в книгах по написанию игр для быстроты работы как раз и рекомендуют применять данный способ.
Восможно я излагаю мысли не совсем понятно... но извиняйте... какой есть.
← →
Sandman25 © (2004-08-09 12:05) [81][80] Prohodil Mimo © (09.08.04 12:04)
Такие переменные не стоит называть переменными цикла.
← →
Prohodil Mimo © (2004-08-09 12:09) [82]А как их назвать, если :
Var
TekRow, TekCol: Word;
Procedure ....
Begin
For TekCol=0 to ColsCount do
For TekRow=0 to RowsCount do
Begin
.........
.........
End;
End;
?????
← →
Думкин © (2004-08-09 12:10) [83]> [80] Prohodil Mimo © (09.08.04 12:04)
Ну так персонально и надо. Да и есть тихое подозрение что там сказано меньше.
> [80] Prohodil Mimo © (09.08.04 12:04)
> А если 10 процедур по обработке таблицы, к примеру обработка
> СтрингГрида, перемещение по строкам, колонкам. В каждой
> процедуре держать эти переменные?
> Каждая процедура может вызывать функции, которые используют
> текущие состояния этих переменных. зачем в них передавать
> значения, если можно объявить их глобально? Чем это плохо?
> не тратится время проца. К тому же в книгах по написанию
> игр для быстроты работы как раз и рекомендуют применять
> данный способ.
Я бы все это в класс внес и его свойства, во-всяком случае постарался.
Но переменную для цикла локально - неа, не буду. Во-всяком случае, пока.
← →
Prohodil Mimo © (2004-08-09 12:12) [84][83] Думкин
>Но переменную для цикла локально - неа, не буду. Во-всяком случае, пока.
Не понял.
← →
Думкин © (2004-08-09 12:13) [85]
> [84] Prohodil Mimo © (09.08.04 12:12)
Ну в смысле попутался. :)
Глобальную под цикл - не буду.
← →
Sandman25 © (2004-08-09 12:14) [86][82] Prohodil Mimo © (09.08.04 12:09)
А как их назвать, если :
Текущие индексы, индексы текущей ячейки. Ничего общего с переменными цикла :)
← →
Яод (2004-08-09 12:14) [87]Prohodil Mimo ©
Каждая процедура может вызывать функции, которые используют текущие состояния этих переменных. зачем в них передавать значения...
Вместо локальных переменных, особенно в циклах, часто бывает использование регистров и это что, медленнее, чем использование глобальных переменных?
← →
Prohodil Mimo © (2004-08-09 12:16) [88][83] Думкин
>Я бы все это в класс внес и его свойства, во-всяком случае постарался.
не всегда изначально знаешь надо вносить в класс или нет. Бывает есть всего пара процедур, зачем для них класс? но когда их становится больше - создаю классы.
← →
Prohodil Mimo © (2004-08-09 12:17) [89][86] Sandman25
Что тогда переменная цыкла?
← →
Prohodil Mimo © (2004-08-09 12:18) [90][87] Яод, а мой вариант настолько криминальный?
← →
Sandman25 © (2004-08-09 12:20) [91][89] Prohodil Mimo © (09.08.04 12:17)
Вызываемые процедуры используют текущие значения индексов без циклов?
← →
Яод (2004-08-09 12:22) [92]Prohodil Mimo ©
компиляторы становятся умнее, чтобы избавить программистов от размышлений, а как тут лучше и во-сколько байт уместить и пытаясь им помешать можешь получить ситуацию наоборот
это так, в общем ...
← →
Prohodil Mimo © (2004-08-09 12:24) [93][91] Sandman25, да.
← →
Sandman25 © (2004-08-09 12:25) [94][93] Prohodil Mimo © (09.08.04 12:24)
Значит это не переменная цикла, а переменная для передачи значения.
← →
Mim1 © (2004-08-09 12:27) [95]
> [79] Sandman25 © (09.08.04 11:47)
Для обьектов не выдастся сообщение "For loop control variable must be simple local variable".
← →
Prohodil Mimo © (2004-08-09 12:29) [96][92] Яод, хочешь сказать, что :
Var
TekRow, TekCol: Word;
Function MyFunc:String;
Begin
......
Result:=....;
End;
Procedure ....
Begin
For TekCol=0 to ColsCount do
For TekRow=0 to RowsCount do
Begin
.........
zz:=MyFunc;
.........
End;
End;
Хуже чем :
Function MyFunc(TekRow, TekCol: Word):String;
Begin
......
Result:=....;
End;
Procedure ....
Var
TekRow, TekCol: Word
Begin
For TekCol=0 to ColsCount do
For TekRow=0 to RowsCount do
Begin
.........
zz:=MyFunc(TekRow, TekCol);
.........
End;
End;
???
← →
Думкин © (2004-08-09 12:30) [97]Да, хуже.
← →
Sandman25 © (2004-08-09 12:32) [98][95] Mim1 © (09.08.04 12:27)
Я знаю. Речь шла не про варнинги, а про эффективность.
← →
Mim1 © (2004-08-09 12:32) [99]
> Prohodil Mimo ©
Слово цикл пишется с буквой и. (надеюсь что у вас опечатка).
← →
Prohodil Mimo © (2004-08-09 12:32) [100][97] Думкин
А обосновать?
← →
Sandman25 © (2004-08-09 12:33) [101][99] Mim1 © (09.08.04 12:32)
Новое предложение должно начинаться с прописной буквы. Надеюсь, Вы совершили опечатку.
← →
Prohodil Mimo © (2004-08-09 12:36) [102][99] Mim1, речь не об грамматике русского языка, но если так, то - опечатка, плюс к тому же уже лет 9 ничего не писал по русски, начинает пробиваться синтакс другого языка :о(
← →
Думкин © (2004-08-09 12:37) [103]
> [100] Prohodil Mimo © (09.08.04 12:32)
А то что функция смысл имеет в контексте внешних переменных. Непрозрачно как-то.
Уж хотя бы так:Procedure ....
Var
TekRow, TekCol: Word;
Function MyFunc:String;
Begin
......
Result:=....;
End;
Begin
For TekCol=0 to ColsCount do
For TekRow=0 to RowsCount do
Begin
.........
zz:=MyFunc;
.........
End;
End;
Безусловно - дело ваше, но для меня подобное - кривость первого порядка.
← →
Prohodil Mimo © (2004-08-09 12:40) [104][103] Думкин, я бы так не сказал... А если в двух процедурах используется эта функция? В каждой из них дублировать функцию?
← →
Думкин © (2004-08-09 12:42) [105]> [104] Prohodil Mimo © (09.08.04 12:40)
Это повод задуматься о том, чтобы нормально ее оформить - сделать таки двуместной.
Если речь об играх и т.п и паранойя на скорость - ну пас.
← →
Prohodil Mimo © (2004-08-09 12:48) [106][105] Думкин,
>паранойя на скорость
Тут Ты прав :о)
По началу пытался научиться писать игры, от туда и осталось жадность до места в памяти и скорость (тогда был ещё ТР7 и ДОС) :о)
[76] в силе? :о)
← →
Prohodil Mimo © (2004-08-09 12:50) [107][105] Думкин,
>Это повод задуматься о том, чтобы нормально ее оформить - сделать таки двуместной.
А если в десяти?
← →
Думкин © (2004-08-09 12:54) [108]> [106] Prohodil Mimo © (09.08.04 12:48)
Я начиналс МК-61, там еще большая паранойя. Потом также ДОС и т.п.
Но для тех задач, что решаю сейчас - мне важнее легкость чтения, управления кодом. Его заведомая безглючность, и желательно на этапе написания впервый раз. Скоростей хватает, а глюки способны и на мощной машине угробить всю скорость выполнения и свести ее к нулю.
> [106] Prohodil Mimo © (09.08.04 12:48)
> [76] в силе? :о)
Смотря что и для чего. Но на данном этапе - возможно. Если это конечно абсолютное кредо. Иногда и в единственном месте вызываемый блок оформляю в функцию. Ну чувство такое - на уровне подкорки.
← →
Думкин © (2004-08-09 12:54) [109]> [107] Prohodil Mimo © (09.08.04 12:50)
Тем более.
← →
Mystic © (2004-08-09 12:56) [110]Prohodil Mimo © (09.08.04 12:29) [96]
Хуже. Навскидку:
1. Могут быть проблемы при многопоточности. Если использовать использоватьтаким обрзом глобальные переменные, то лучше всего описывать их как threadvar.
2. Проблемы при вложеных вызовых. Надо всегда помнить, где какая переменная цикла используется, чтобы случайно не использовать ее во вложеном вызове.
3. Использования глобальных переменных отключает некоторые хинты/предупреждения.
4. При оптимизации кода компилятор всестолокальных переменных может использовать регистры. А в случае глобальных переменных --- лишен этой возможности. Лишние инструкции.
3. Оптимизация.
← →
Anatoly Podgoretsky © (2004-08-09 13:04) [111]Prohodil Mimo © (09.08.04 12:48) [106]
Если речь идет о месте в памяти, то тем более локальные переменные, хоть тысяча функций, а занято будет всего 4 байта на стеке. С глобальными память будет занята до конца работы программы.
← →
Prohodil Mimo © (2004-08-09 13:11) [112][108] Думкин,
ну глюков по этим причинам я ещё ни разу не собирал.
> желательно на этапе написания впервый раз
Это когда всё по полочкам разложено. А если не знаешь что тебя ждёт впереди? Например, как сейчас, пишу программу, условия меняются чуть ли не каждый день, какк тут с первого раза написать, да ещё и гибкий код. Уже научился предвидеть возможные варианты и писать код более менее гибкий, что бы в случае очередных изменений не писать всё с нуля.
А по поводу использования функции в нескольких процедурах скажу так :
понадобилось написать определённую процедуру... написал... через время мне говорят написать другую процедуру... пишу... местами в ней есть точно такой же код как и в первой. почему бы не вынести этот код в отдельную процедуру\функцию? И зачем его туда было выносить в момент написания первой процедуры, когда о второй ещё даже и речи не было?
Одно дело когда он используется несколько раз в процедуре (и то, создаётся локальная функцыя), но когда один...
В итоге - с первого раза не получается.
← →
Anatoly Podgoretsky © (2004-08-09 13:16) [113]Prohodil Mimo © (09.08.04 13:11) [112]
ну глюков по этим причинам я ещё ни разу не собирал.
Ну все впереди, а остальное придет со временем, если конечно будешь слушаться компилятор и думать, думать, думать.
← →
Prohodil Mimo © (2004-08-09 13:18) [114][110] Mystic
1. Могут быть проблемы при многопоточности. Если использовать использоватьтаким обрзом глобальные переменные, то лучше всего описывать их как threadvar.
Это совсем другое дело.
2. Проблемы при вложеных вызовых. Надо всегда помнить, где какая переменная цикла используется, чтобы случайно не использовать ее во вложеном вызове.
Во вложенном не используются циклы или используются свои переменные.
[111] Anatoly Podgoretsky,
а если они мне нужны в 90% всей программы?
← →
Яод (2004-08-09 13:21) [115]Prohodil Mimo ©
для оптимизации не нужно пытаться перелопачивать весь код, а только самые длинные или часто вызываемые места
если уж не уверен, надо смотреть уже в ассемблер-коде, как используются те или иные переменные
← →
Prohodil Mimo © (2004-08-09 13:21) [116][113] Anatoly Podgoretsky, чем собственно и занимаемся.
Раньше учили так, теперь по другому. :о(
Подскажите хотя бы где почитать о том как нужно оптимизировать проги для "современных компиляторов"? (ответы : в книгах, в инете - я знаю, мне бы более конкретно)
← →
Игорь Шевченко © (2004-08-09 13:22) [117]Prohodil Mimo © (09.08.04 13:18)
Самая большая ошибка (на мой взгляд) при использовании глобальных переменных в данном случае, это то, что код становится нечитаемым. А разговоры насчет скорости и экономии памяти можно оставить для тех старых времен, когда компьютеры были меленными и память мерялась миллибайтами.
← →
Prohodil Mimo © (2004-08-09 13:23) [118][115] Яод.
Не понял к чему это. Я вроде бы не писал подобного.
← →
Anatoly Podgoretsky © (2004-08-09 13:26) [119]П6ременные цикла, на протяжении жизни программы :-)
← →
Mystic © (2004-08-09 13:30) [120]Раньше учили так, теперь по другому
Во все времена локальные переменные лучше было определять локально. Нежелание их переопределять в теле каждой процедуры можно объяснить только ленью.
← →
Prohodil Mimo © (2004-08-09 13:31) [121][117] Игорь Шевченко
> Самая большая ошибка (на мой взгляд) при использовании глобальных
> переменных в данном случае, это то, что код становится нечитаемым.
Это почему? Мне так наоборот - лишние строки мешают читать.
> А разговоры насчет скорости и экономии памяти можно оставить
> для тех старых времен, когда компьютеры были меленными и
> память мерялась миллибайтами
Вот потому то и тормозят все новые проги на чутка старых машинах (те которым год-два).
Раньше писали, старались ужать, оптимизировать, сделать скорость быстрее... а сейчас? А сейчас - не устраивает скорость - я не виноват, что у тебя не самий лучший комп на данный момент... иди меняй.
← →
Prohodil Mimo © (2004-08-09 13:33) [122][119] Anatoly Podgoretsky, речь уже пошла о глобальных переменных, а не о переменных цикла.
← →
Prohodil Mimo © (2004-08-09 13:34) [123][120] Mystic, определять что лучше надо для каждого случая отдельно.
← →
Думкин © (2004-08-09 13:35) [124]> [121] Prohodil Mimo © (09.08.04 13:31)
Это потому что ты свой 10 минут назад писанный код читаешь.
А компы ускоряют только из спортивного интереса? Видимо и для того чтобы можно было создавать более сложные структуры.
Вот задача с количеством установленных битов в байте: Самое то сейчас - это использовать массив - большой, но и быстрый и главное простой.
А в требованиях к программе - требования к железу.
← →
Anatoly Podgoretsky © (2004-08-09 13:39) [125]Prohodil Mimo © (09.08.04 13:31) [121]
Ты думаешь из за глобальных/локальных переменных :-)
← →
Игорь Шевченко © (2004-08-09 13:44) [126]
> Это почему? Мне так наоборот - лишние строки мешают читать.
Мне тоже, как ни странно, лишние строки мешают читать. Но еще больше мне мешает читать тот факт, что объявление локальной (по своей сути) переменной нужно искать за пределами функции.
← →
nikkie © (2004-08-09 13:46) [127]>>2. Проблемы при вложеных вызовых. Надо всегда помнить, где какая
>>переменная цикла используется, чтобы случайно не использовать ее
>>во вложеном вызове.
>Во вложенном не используются циклы или используются свои переменные.
это пока так. а через месяц или через год понадобится во вложенном вызове вставить вызов процедуры, которая использует эти переменные. что тогда? надо помнить всю структуру вызовов, чтобы недопустить такого? зачем напрягать себя размышлениями на тему где и как используются эти глобальные переменные? да и уверен ли, что будешь помнить? а если другой человек будет вносить изменения?
← →
Prohodil Mimo © (2004-08-09 13:46) [128][124] Думкин
> Это потому что ты свой 10 минут назад писанный код читаешь.
Это был пример из головы, а не из программы.
а с остальным я не спорю.
> А в требованиях к программе - требования к железу.
Выходит если мне нужна какая-то прога и мой комп уже не соответствует её требованиям, то я должен бежать в магазин за новой? и так каждый год? (забота о клиенте)
Судя по играм - так оно и есть... но я в них не играю.
← →
Anatoly Podgoretsky © (2004-08-09 13:49) [129]Если нужна, то да. Кроме игр таких очень мало.
← →
Думкин © (2004-08-09 13:50) [130]> [128] Prohodil Mimo © (09.08.04 13:46)
Это передергивание все-же.
← →
Prohodil Mimo © (2004-08-09 13:52) [131][127] nikkie, как это можно из одного отчёта вызывать другой? и когда это может понадобиться? Такие переменные я использую в процедурах, которые друг друга вызавать не могут, уж как ты ни хоти. Написать то конечно можно, но .....
← →
Юрий Зотов © (2004-08-09 13:52) [132]> Prohodil Mimo © (09.08.04 12:48) [106]
> По началу пытался научиться писать игры, от туда и осталось
> жадность до места в памяти и скорость
Тогда тем более. Локальные переменные циклов for компилятор "размещает" в регистрах - то есть, экономится память и повышается скорость. Ведь Вы именно этого хотите?
← →
VMcL © (2004-08-09 14:04) [133]>>Юрий Зотов © (09.08.04 13:52) [132]
Поправка:
Локальные переменные циклов for компилятор по возможности "размещает" в регистрах...
← →
nikkie © (2004-08-09 14:51) [134]>nikkie, как это можно из одного отчёта вызывать другой?
первый раз слышу про какие-то отчеты. разговор был про то, что у тебя есть несколько процедур, использующих циклы по паре глобальных переменных (для прохода по гриду). эти процедуры вызывают некоторые другие процедуры-функции, но которые уже эти глобальные переменные не изменяют. вот я и попытался спросить тебя - откуда такая уверенность, что никогда ни одна из вызываемых процедур-функций не изменит
и когда это может понадобиться?
сегодня ты печатаешь табличку значений (a_ij)for Row := 1 to RowCount do
for Col := 1 to ColCount do
Print(A[Row][Col]);
завтра тебя просят напечатать не абсолютные значения, а в процентах. 100% - это сумма всех элементов в строке. ты пишешь:for Row := 1 to RowCount do
begin
RowSum := GetRowSum;
for Col := 1 to ColCount do
Print(A[Row][Col] / RowSum * 100);
end;
function GetRowSum: Double;
begin
Result := 0;
for Col := 1 to ColCount do
Result := Result + A[Row][Col];
end;
м-да, Col получается изменяется внутри GetSum - но ты спокоен, поскольку GetSum вызывается вне цикла по Col.
а через месяц выясняется, что делить надо не только на сумму элементов в строке, но и на сумму элементов в столбце. и ты побыстрому все исправляешь:for Row := 1 to RowCount do
begin
RowSum := GetRowSum;
for Col := 1 to ColCount do
begin
ColSum := GetColSum;
Print(A[Row][Col] / RowSum / ColSum);
end;
end;
function GetRowSum: Double;
begin
Result := 0;
for Col := 1 to ColCount do
Result := Result + A[Row][Col];
end;
function GetColSum: Double;
begin
Result := 0;
for Row := 1 to RowCount do
Result := Result + A[Row][Col];
end;
← →
Prohodil Mimo © (2004-08-09 16:12) [135]смысл такой :
есть процедуры, которые никак не могут вызывать друг друга и в момент работы одной из них никакая другая работать не будет (потоков не используется). Эти процедуры используют одинаковые переменные (тип, название). Вся программа только и состоит в том, что бывызывать эти процедуры. Переменные не обязательно для цикла. Есть функции, которые используют текущие значения этих переменных, не изменяя их.
я согласен : безопаснее все переменные держать локально и каждый раз передавать в функцию.
Но быстрее ли это?
И настолько ли плохо держать их глобально?
← →
Игорь Шевченко © (2004-08-09 16:15) [136]
> И настолько ли плохо держать их глобально?
Уже несколько человек ответили, насколько плохо.
Для наколенных поделок можно и глобальными держать, коран не запрещает, компилятор тоже.
← →
Danilka © (2004-08-09 16:17) [137][135] Prohodil Mimo © (09.08.04 16:12)
Дык, быстрее всего вообще функции/процедуры не использовать, зачем лишние команды вызовов/возвратов? :))
Все это, по моему скромному мнению, ерунда. Такая оптимизация. Выгадывать пару лишних тактов в ущерб всего.
Честно говоря, полтора года назад достался в наследство проект в котором часто использовались глобальные переменные, вобщем, все глюки победить так и не удалось, хотя по-возможности вычистил большинство глобальных перемен, но теперь я их просто-напросто ненавижу. :))
← →
Anatoly Podgoretsky © (2004-08-09 16:18) [138]Prohodil Mimo © (09.08.04 16:12) [135]
Значительно быстрее, вот когда потратишь недели на поиск ошибки, да еще и не найдешь, тогда поймешь, если захочешь понять.
← →
Prohodil Mimo © (2004-08-09 16:22) [139][138] Anatoly Podgoretsky, за 8 лет такой проблемы ни разу не испытал
← →
Яод (2004-08-09 16:22) [140]Сам когда-то занимался вылизыванием, еще на древнем паскале ради скорости и экономии.
Теперь смотришь на это и думаешь и зачем оно надо было?
Хотя графику в то время могли бы сделать пошустрее, где эта переносимость сейчас?
← →
Anatoly Podgoretsky © (2004-08-09 16:24) [141]Prohodil Mimo © (09.08.04 16:22) [139]
Позволю себе не поверить, закон бутерброда неотвратим.
← →
Danilka © (2004-08-09 16:26) [142][141] Anatoly Podgoretsky © (09.08.04 16:24)
Ну почему-же. Смотря чем заниматься эти 8 лет. На очень маленьких проектах глабальные переменные может и не вылезут боком.
← →
Prohodil Mimo © (2004-08-09 16:32) [143][141] Anatoly Podgoretsky, я не против.
Ну мож когда-нибудь и приспичит :о)
Я так понял, что писать надо удобно и не стараться ничего оптимизировать (всё равно компы сейчас быстрые, справятся) ?
Но когда запускаю прогу на старенькой машине сразу возникает желание оптимизировать, что бы хотя-бы на 30% работало быстрее.
Вот пришёл заказчик, хочет прогу, компы старые, а я должен сказать "обнови сперва машины, потом заходи" ?
← →
Мастер © (2004-08-09 16:35) [144]... Вся программа только и состоит в том, что бывызывать эти процедуры...
И что, все программы такие? Или других просто нет?
← →
Anatoly Podgoretsky © (2004-08-09 16:35) [145]Использование локальных переменных, особенно для циклов это и есть оптимизация, в плане скорости и размера потребной памяти.
← →
Danilka © (2004-08-09 16:37) [146][143] Prohodil Mimo © (09.08.04 16:32)
Оптимизация, это совсем другое. Оптимизируются критичные по времени выполнения и/или объему места, а не передача параметров функции/процедуре. Вычищать параметры для оптимизации - все-равно что мухубойкой шлоепать слона пытаясь запихнуть его в чемодан.
← →
Prohodil Mimo © (2004-08-09 16:53) [147][144] Мастер, вот любят тут к словам придираться.
Это был только пример.
← →
Prohodil Mimo © (2004-08-09 17:03) [148]Ветку уже надо переименовать в "Нужно ли бороться с Prohodil Mimo ?" :о)
← →
Яод (2004-08-09 17:11) [149]Prohodil Mimo ©
боюсь ее оптимизируют удалением лишних веткописателей
← →
Prohodil Mimo © (2004-08-09 17:21) [150]И все ники вынесут глобально
← →
Думкин © (2004-08-10 06:34) [151]> Prohodil Mimo ©
Если между функциями начинает перемещаться огромное количество параметров, то есть смысл подумать о структуре, которую можно передавать по ссылке.
Вот ведь сколько в Windows структур и и т.д и т.п и работает.
Хотя уже предвижу выпады от иных - а потому и тормозит и вообще маст дай.
Но если подумать?
← →
Prohodil Mimo © (2004-08-10 10:13) [152][151] Думкин.
Бедняга. Наверное не спал всю ночь :о)
Можно и твой вариант попробовать на тестах, посмотреть что будет. Как появится минутка - попробую. Ты же имел в виду указатель (pointer) на структуру (record)?
← →
Думкин © (2004-08-10 10:14) [153]> [152] Prohodil Mimo © (10.08.04 10:13)
> Бедняга. Наверное не спал всю ночь :о)
Не понял.
← →
Sandman25 © (2004-08-10 10:16) [154][152] Prohodil Mimo © (10.08.04 10:13)
Скорее, var MyRecord или const MyRecord
← →
Prohodil Mimo © (2004-08-10 10:34) [155][153] Думкин, не обижайся... это шутка была :о)
просто время 06:34 - довольно раннее :о)
← →
Думкин © (2004-08-10 10:37) [156]> [155] Prohodil Mimo © (10.08.04 10:34)
Пол десятого я обычно не сплю. :)
Страницы: 1 2 3 4 вся ветка
Текущий архив: 2004.08.29;
Скачать: CL | DM;
Память: 0.93 MB
Время: 0.037 c