Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2004.09.12;
Скачать: [xml.tar.bz2];

Вниз

Нужно ли бороться с хинтами и ворнингами - 2   Найти похожие ветки 

 
Sergey Masloff   (2004-08-10 20:32) [0]

Или 1423 строчки кода которые потрясли мир (ну если и не мир то меня - точно).
 Пришлось тут сегодня покопаться в чужом коде. Делали для нас оутсорсеры кое-какую работу. Давно - почти 3 года назад. Все честь по чести контора серьезная контракт, ТЗ, приемка - сдача. Ну со сроками подзатянули чуток но все вроде заработало худо-бедно. Ну а тут пришлось кое-что подкрутить, да даже не подкрутить а посмотреть как одна вещь там работает и можно ли настроить под немножко другую задачу. Ну я взял исходники - думал на часик работы. И что я там увидел - это нечто. Наверное пост будет длинный - предупреждаю сразу.
 Для примера возьму один из модулей (от остальных полутора десятков отличается только тем что то что меня интересовало в нем реализовано). Начало меня обрадовало - компилятор с ходу выдал 183 хинта и около 50 варнингов. Тыкнув в первый же ворнинг я увидел чудо-конструкцию №1(привожу сокращенный вариант):

procedure SomeProc();
var
 bOK : Boolean;
begin
 if bOK then
    {Супер пупер код }
 else
    {Другой супер-пупер код}
end;


беглый просмотр модуля выявил еще 3 таких же участка. Такой видимо вариант русской рулетки

Код номер №2 меня уже не удивил

procedure SomeProc();
var
 bOK : Boolean;
begin
 if SomeCond then
   bOK := True
 else if SomeOtherCond then
   bOk := True
 else
   .....
 end;
 {Тут ничего связанного с использованием bOK нет}
end;


Таких было 6 штук

еще неплохой пример

procedure SomeProc();
var
 X1 : TSomeType;
 X2 : TOtherType;
 ...
 XN : TSomeNType;
begin
   {Тут ничего ни одна из локальных переменных не используется}
end;

такое встречалось раз 30 то есть практически в каждой процедуре

...ПРОДОЛЖЕНИЕ СЛЕДУЕТ


 
Юрий Зотов ©   (2004-08-10 20:38) [1]

Если SomeCond и SomeOtherCond в коде № 2 связаны с вызовом процедур, то код все же может быть оправдан - он не зависит от используемой схемы вычисления булевских выражений. А его аналог:
bOK := SomeCond or SomeOtherCond;
от нее зависит (SomeOtherCond может вычисляться, а может и нет).


 
Rouse_ ©   (2004-08-10 20:45) [2]

На дух не переношу вещей даже с хинтами, не говоря уже о ворнингах...
Код должен быть изначально верен и не допускать даже возможности возникновения ошибки (за исключением ошибок компилятора :)

> [1] Юрий Зотов ©   (10.08.04 20:38)
Если верить {Тут ничего связанного с использованием bOK нет} то налицо зашумленность кода, а так действительно SomeCond or SomeOtherCond

Вот такое мое ИМХО


 
Sergey Masloff   (2004-08-10 20:48) [3]

...ПРОДОЛЖЕНИЕ

Ну дальше я читал просто как комикс, например

procedure SomeProc();
var
 F : TSomeFormType;
begin
 if SomeCond then
   F := TSomeFormType.Create(nil);
 {тут всякий разный код в том числе использующий F}
 with F do begin
   SomeMehod();
   SomeOtherMethod();
   try
     SomeThirdMethod();
   finally
     Free;
   end;
 end;
end;

Таких было 3 вхождения

Зато было очень много комментариев. В пяти местах встречалось

 inc(i); {увеличиваем i}
 // Мой коммент - лучше б написали за каким ИКСОМ тут i когда нигде дальше не используется


Но больше всего мне понравился следующий комментарий (ДОСЛОВНО):

END.//КОНЕЦ
{************  Конец модуля  *************************}


Кстати еще одна находка - переменные цикла вне цикла использовались В КАЖДОЙ процедуре в которой был цикл. Буквально в каждой.

И напоследок - зачем я это написал. Может быть чтобы показать какой я умный? - нет, это и так все знают ;-)))) Чтобы замеряться с кем - нибудь - нет.
 Просто этот код писали люди считающие себя профессиональными программистами. Работающие (надеюсь что работавшие) в серьезной конторе. Не вчерашние студенты - примерно мои ровесники, за 30.
 Так вот для чего я это пишу - ребята, кто делает первые шаги или чуть больше, запомните-так писать нельзя. Это может проканать раз, может два. Это переходит в привычку - так писать. А мир программистский тесен. Я, не самый общительный в мире человек хорошо знаю коллег из минимум полутора десятков серьезных компаний. Думаю многие знают больше. Мы общаемся, и я вполне могу скажем при приеме на работу кандидата обзвонить своих знакомых - не знают ли такого. И они мне могут позвонить - и звонят. Ну и как я отрекомендую авторов такого кода? Причем люди не стемнялись, с каждом комментарии авторы чуть ли не с копирайтами.

 Так что берегите честь смолоду! Вляпаться легко отмыться потом - намного сложнее. Шутка но всерьез.

 С уважением


 
nikkie ©   (2004-08-10 20:49) [4]

ну уже весело :))
ждем продолжения :)


 
Sergey Masloff   (2004-08-10 20:51) [5]

Rouse_ ©   (10.08.04 20:45) [2]
>Если верить {...
зуб даю ;-) - не исполльзуется.


 
DiamondShark ©   (2004-08-10 21:11) [6]


> Юрий Зотов ©   (10.08.04 20:38) [1]
> Если SomeCond и SomeOtherCond в коде № 2 связаны с вызовом
> процедур, то код все же может быть оправдан - он не зависит
> от используемой схемы вычисления булевских выражений. А
> его аналог:
> bOK := SomeCond or SomeOtherCond;
> от нее зависит (SomeOtherCond может вычисляться, а может
> и нет).

Вечер трудного дня?


 
Cobalt ©   (2004-08-10 21:12) [7]

А как товарищи матёрые программисты относятся к таким вот хинтам:
[Warning] Unit1.pas(584): Unsafe typecast of "Integer" to "TObject"
[Warning] Unit1.pas(616): Unsafe typecast of "TObject" to "Integer"
И код к ним:

 s2:=FieldByName("CompanyName").AsString;
  if pos(AnsiUpperCase(s),AnsiUpperCase(s2))<>0
  then ClLBox.Items.AddObject(s2,TObject(FieldByName("ID").AsInteger));
---------
CLFId:=integer(ClLBox.Items.Objects[ClLBox.ItemIndex]);


 
jack128 ©   (2004-08-10 21:14) [8]

не знаю как матерые, а я бы отключил в семерке предепреждения об unsafe коде ;-)


 
имя   (2004-08-10 21:20) [9]

Удалено модератором


 
имя   (2004-08-10 21:20) [10]

Удалено модератором


 
имя   (2004-08-10 21:20) [11]

Удалено модератором


 
имя   (2004-08-10 21:20) [12]

Удалено модератором


 
имя   (2004-08-10 21:20) [13]

Удалено модератором


 
имя   (2004-08-10 21:20) [14]

Удалено модератором


 
имя   (2004-08-10 21:20) [15]

Удалено модератором


 
Юрий Зотов ©   (2004-08-10 21:23) [16]

> DiamondShark ©   (10.08.04 21:11) [6]
У Вас?

> jack128 ©   (10.08.04 21:14) [8]
А кто мешает?


 
jack128 ©   (2004-08-10 21:27) [17]


> > jack128 ©   (10.08.04 21:14) [8]
> А кто мешает?

Мне? То что я на пятёрке сижу ;-)  А вот что Кобальту мешает - не знаю..


 
Cobalt ©   (2004-08-10 21:34) [18]

2 Юрий Зотов ©   (10.08.04 21:23) [16]
То есть, вы хотите сказать, что этот хинт указывает на возможные проблемы при переносе на .Net ?
И при отсутствии таких перспектив можно не обращать внимание на него и отключить?


 
имя   (2004-08-10 21:41) [19]

Удалено модератором


 
имя   (2004-08-10 21:41) [20]

Удалено модератором


 
имя   (2004-08-10 21:41) [21]

Удалено модератором


 
Юрий Зотов ©   (2004-08-10 21:59) [22]

> Cobalt ©   (10.08.04 21:34) [18]

Я так и сделал. А заодно отключил и предупреждения о платформенной зависимости. Потому что проект изначально писался, как чисто виндовый, никаких дотнетов и кроссплатформенности в нем даже и в перспективе не появится. Иначе проще будет новый написать.


 
GuAV ©   (2004-08-10 22:02) [23]


> не знаю как матерые, а я бы отключил в семерке предепреждения
> об unsafe коде ;-)

Ага среди них правильных ворнингов не видно - этих слишком много :)
У себя их гашу даже не директивами а опциями.

+ platform - эти на кой?


 
Piter ©   (2004-08-10 22:09) [24]

Sergey Masloff   (10.08.04 20:48) [3]
Кстати еще одна находка - переменные цикла вне цикла использовались В КАЖДОЙ процедуре в которой был цикл. Буквально в каждой


ну я тоже так делаю. Если цикл уже отработал и локальная абстрактная переменная i уже не нужна - почему бы ее не задействовать? не объявлять же новую (можно, но зачем?).

А вообще - ну подумаешь что такое есть. Проект ведь компилировался с оптимизацией, значит все что объявлено, но не использовано - было выброшено компилятором. И получающийся код не такой уж и плохой.

А так ты же сам говорил про сроки, небось спешили, просто забыли убрать объявления переменных (может хотели по другому реализовать, но в спешке не стали).

Ну это я так. Склонен сегодня к адвокатству

Cobalt ©   (10.08.04 21:34) [18]
То есть, вы хотите сказать, что этот хинт указывает на возможные проблемы при переносе на .Net ?


это вообще может породить проблемы. Сам подумай - число приводишь к TObject - ясно, что это небезопасно. Компилятор же не может понять, что ты используешь ListBox для хранения строки и просто приписанного к нему числа...


 
Piter ©   (2004-08-10 22:10) [25]

GuAV ©   (10.08.04 22:02) [23]
Ага среди них правильных ворнингов не видно - этих слишком много :)


А у меня семерка по умолчанию никогда и не выводила warning на Unsafe код


 
Anatoly Podgoretsky ©   (2004-08-10 22:14) [26]

Злой ты человек, думал спать буду спокойно, но после такого не получится :-)


 
Юрий Зотов ©   (2004-08-10 22:19) [27]

> Piter ©   (10.08.04 22:09) [24]

> Если цикл уже отработал и локальная абстрактная переменная i
> уже не нужна - почему бы ее не задействовать? не объявлять же
> новую (можно, но зачем?).

Используя счетчик цикла вне цикла, Вы заставляете компилятор разместить его обязательно в памяти. А без этого он мог бы разместить его в регистре.


 
Юрий Зотов ©   (2004-08-10 22:25) [28]

Поправка к [27].

Хотя надо смотреть ассемблерный код - не исключено, что компилятор достаточно умен и все равно строит цикл по регистру.


 
Rouse_ ©   (2004-08-10 22:31) [29]

> Кстати еще одна находка - переменные цикла вне цикла использовались
> В КАЖДОЙ процедуре в которой был цикл.

Я что-то никак раздуплить не могу :) Приведи код, а то не понятно что кого и в каких местах пользует :))


 
Юрий Зотов ©   (2004-08-10 22:34) [30]

> Rouse_ ©   (10.08.04 22:31) [29]

Насколько я понял, имеется в виду вот что:

for I := ... to ... do
begin
 ...
end;
I := ...
... // дальше работаем с I


 
jack128 ©   (2004-08-10 22:37) [31]


> > Кстати еще одна находка - переменные цикла вне цикла использовались
>
> > В КАЖДОЙ процедуре в которой был цикл.
все таки я пока не понимаю всей "позорности" такой практики.. ЮЗ [27] - это не причина, ИМХО.


 
Sergey Masloff   (2004-08-10 22:41) [32]

Юрий Зотов ©   (10.08.04 22:34) [30]
Несколько хуже

for I := ... to ... do
begin
...
end;

I := ... <<== ЭТОГО не было. То есть именно работа с тем что там после цикла осталось

... // дальше работаем с I


 
GuAV ©   (2004-08-10 22:42) [33]


> А у меня семерка по умолчанию никогда и не выводила warning
> на Unsafe код

Она выводит или новый проэкт создать или старый открывать а в другом случае они октл, когда точно что - не помню.


 
Ihor Osov'yak ©   (2004-08-10 22:43) [34]

2 Cobalt ©   (10.08.04 21:12) [7]

Нормально отношусь. Ибо по существу. Особенно в предверии перехода к дотнету.   Если же в коллекции вместо указателя ставим сознательно какой-то целочисельный идентификатор - что впрочем, есть вполне нормальной практикой в мире win32 - сознательно отключаем сотв. варнинг. Это один из тех немногих случаев, когда соотв. варнинги есть смысл отключать.


 
Юрий Зотов ©   (2004-08-10 22:47) [35]

> Sergey Masloff   (10.08.04 22:41) [32]

Да-а-а... Слов нет, одни буквы. И это работало?


 
Sergey Masloff   (2004-08-10 22:52) [36]

Юрий Зотов ©   (10.08.04 22:47) [35]
>И это работало?
Ну вобщем, работало. Ну эпизодически происходили всякие побочные эффекты. Типа при запуске на одних и тех же данных то отрабатывало то нет, то обращение к памяти по 0 адресу но вобщем приемный акт им подписали да и использовалась программа все это время. С сегодняшнего дня правда не используется.


 
Rouse_ ©   (2004-08-10 22:54) [37]

> [32] Sergey Masloff   (10.08.04 22:41)
Хм, даю пример:

for I := 0 to Len - 1 do
 if Buff[I] = Условие then Break;
if I < Len then (Выполняем операции с Buff[I])

Довольно нормальный код, или я не так понял и все намного запущеней?

ЗЫ: Я сам часто использую повторно переменные типа I после их повторной инициализации и только потому, что не вижу смысла создавать кучу временных переменных...


 
Юрий Зотов ©   (2004-08-10 22:56) [38]

> Sergey Masloff   (10.08.04 22:52) [36]

> при запуске на одних и тех же данных то отрабатывало то нет,
> то обращение к памяти по 0 адресу

Неудивительно. Только я бы не называл это "работало".

> вобщем приемный акт им подписали

IMHO, поторопились. Стоило сначала посмотреть код.


 
Юрий Зотов ©   (2004-08-10 22:59) [39]

> 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 после выхода из цикла может быть любым.


 
Rouse_ ©   (2004-08-10 23:01) [40]

> Если компилятор построит цикл по регистру, значение I после
> выхода из цикла может быть любым.

В смысле ты имеешь ввиду если цикл пройдет до конца и условие не выполнится ни одного раза (не сработает Break)?



Страницы: 1 2 3 4 вся ветка

Форум: "Потрепаться";
Текущий архив: 2004.09.12;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.57 MB
Время: 0.035 c
1-1093422966
Vadim X
2004-08-25 12:36
2004.09.12
Kylix3


1-1093847121
samumka
2004-08-30 10:25
2004.09.12
Функция InputBox()


4-1091120974
DeMus
2004-07-29 21:09
2004.09.12
Как подключить в программе кассовый аппарат


1-1093712107
Черный дембель
2004-08-28 20:55
2004.09.12
Параметры функций из DLL


1-1093237558
Teenager
2004-08-23 09:05
2004.09.12
Как можно создать простой справочник?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский