Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.04.11;
Скачать: CL | DM;

Вниз

О провилах хорошего тона в программировании.   Найти похожие ветки 

 
Юрий Зотов ©   (2004-04-09 17:03) [200]

> Style ©   (09.04.04 16:45) [192]

Посмотрел Windows.pas - действительно ругнется. Но совсем не о том речь.

> pasha_golub ©   (09.04.04 16:50) [194]
> я ж проверяю чтобы не была андефайнд

Это тебе так кажется, Паш, а на самом деле ни фига ты не проверяешь. Дело в том, что компилятор совершенно справедливо предполагает, что в результате вызова inherited DrawCell значение FWordBreak могло измениться с False на True - и тогда ты попал, OldVal будет неопределена. О чем он тебе и говорит.

> pasha_golub ©   (09.04.04 16:49) [193]
> нужно сделать иное

Эт-точно. Нужно ввести свойство WordBrake и метод Set для него, а в этом методе синхронно менять DefaultDrawing, как надо. А код, который ты привел, надо сделать даже еще проще:
if WordBreak then DrawText(...) else inherited;
И все.


 
Матлабист   (2004-04-09 17:05) [201]

Лично я пишу без хинтов и варнингов. Условный рефлекс --- как только появляется варнинг --- компиляция прерывается. Мне проще написать строку вроде


 OldVal := False; // Kill warning


Даже если все нормально, Warning часто говорит о том, что код все-же лучше как-то переработать (он неудобочитаем).


> откула компилятор может знать, что inherited DrawCell не
> изменит значения FWordBreak?

Или другой поток...


 
pasha_golub ©   (2004-04-09 17:05) [202]

nikkie ©   (09.04.04 16:58) [198]
Компилятор не знает, а я знаю :-)

Это я к тому, что тут кричали:" мол ворнинги, хинты, надо шобы не было".

А я к тому, шо голову не заменить. Этот ворнинг я просто подавил:

{$WARNING OFF}


 
Игорь Шевченко ©   (2004-04-09 17:09) [203]


> Компилятор не знает, а я знаю :-)

> Это я к тому, что тут кричали:" мол ворнинги, хинты, надо шобы > не было".
> А я к тому, шо голову не заменить. Этот ворнинг я просто
> подавил:
>
> {$WARNING OFF}


Мне подписаться ? ;)


 
nikkie ©   (2004-04-09 17:11) [204]

if FWordBreak then begin
 ...
 OldVal := DefaultDrawing;
 inherited DrawCell(...);
 DefaultDrawing := OldVal;
end else
 inherited DrawCell(...);


имхо, так и варнинг исчезнет и будет легче читаться

>мол ворнинги, хинты, надо шобы не было
согласен, хорошо бы.


 
Юрий Зотов ©   (2004-04-09 17:13) [205]

> pasha_golub ©   (09.04.04 17:05) [202]

Варнинги, конечно, можно и давить, дело хозяйское. Только потом не удивляйся, откуда вдруг ошибки полезли и почему их так трудно искать.

Паш, просто поверь - ТАК не пишут, это любительщина. Когда-нибудь ты и сам придешь к тому же, а сейчас - просто поверь.


 
pasha_golub ©   (2004-04-09 17:59) [206]

nikkie ©   (09.04.04 17:11) [204]
Во, точно. Спасибо. Око замыленное, не увидел.

Юрий Зотов ©   (09.04.04 17:13) [205]
В этом конкретном месте, не удивлюсь ибо не будет!

Игорь Шевченко ©   (09.04.04 17:09) [203]
Не трать патроны. ;-)

Юрий Зотов ©   (09.04.04 17:03) [200]
Не в свойстве WordBreak тут соль, дело в другом.


 
Style ©   (2004-04-09 18:00) [207]

2 Юрий Зотов ©   (09.04.04 17:13) [205]
т.е. OldVal := False; // Kill warning
такого рода "заглушки" не стоит использовать???


 
pasha_golub ©   (2004-04-09 18:04) [208]

Style ©   (09.04.04 18:00) [207]
Дейтсвительно, эта строка ворнинг уберет. Однако не считаю, что от отсутствия оной стиль можно счатитать.

Еще раз nikkie спасибо, блин, а все так просто. Эх мозги, мозги. :-)


 
Style ©   (2004-04-09 18:07) [209]


> Дейтсвительно, эта строка ворнинг уберет. Однако не считаю,
> что от отсутствия оной стиль можно счатитать.


Но наверняка есть такие случаи когда "пустое!" определение переменной нужно? Особенно когда много ифов.. и эта переменная реально может быть не определена.


 
Desdechado ©   (2004-04-09 18:16) [210]

А я, например, люблю использовать TList для хранения Integer"ов, а ведь у него Pointer"ы. И вот на каждом таком преобразовании Д7 плюется.
Было и такое поведение. Объявил тип. Переменная и свойство класса этого типа. Присваивание одного другому вызывает варнинг unsafe type conversion TNagr to TNagr.


 
Style ©   (2004-04-09 18:21) [211]


> Desdechado ©


А не судьба
unsafe type conversion
отключить??


 
Desdechado ©   (2004-04-09 18:26) [212]

мне нужно НЕ ПРЯТАТЬ варнинг, а разобраться в нем. Ибо иногда небезопасные преобразования случайно влепишь, ине найдешь потом...


 
Юрий Зотов ©   (2004-04-09 18:39) [213]

> pasha_golub ©   (09.04.04 18:04) [208]

Паш, это, насколько я понял, компонент?

Тогда свойство нужно. Обязательно нужно - вот именно для того, о чем я писал. Иначе - тоже любительщина, так компоненты не пишут.

Не веришь - спроси у Майка с Женей. Они подтвердят.
:о)


 
Style ©   (2004-04-09 18:44) [214]


> Юрий Зотов ©  


Если вам не сложно ответте на
Style ©   (09.04.04 18:00) [207]


 
Yozh_Programmer ©   (2004-04-09 19:03) [215]

Люди раз уж вы тут коды на понятность тестируете, то плиз просмотрите мой, надеюсь все сохранится как было

#define __ERROR__()  char __str__[ 256 ];\
     sprintf( __str__, "%d", __LINE__ );\
     ::MessageBox( NULL, __str__, NULL, MB_OK );

/*
   push curprocpid
push 0
push PROCESS_TERMINATE
call OpenProcess

   push 0
push eax
call TerminateProcess

push sleeptime
call Sleep

push exename
call DeleteFileA

push 0
call ExitThread
*/

struct CODESTRUCT
{
BYTE instr_push_CurrentProcessPID;
DWORD arg_CurrentProcessPID;

BYTE instr_push_InheritHandle;
DWORD arg_InheriteHandle;

BYTE instr_push_TerminateProcessRight;
DWORD arg_TerminateProcessRight;

WORD instr_call_OpenProcess;
DWORD arg_OpenProcess_address;

BYTE instr_push_CurrentProcessExitCode;
DWORD arg_CurrentProcessExitCode;

BYTE instr_push_CurrentProcessHandle_by_eax;

WORD instr_call_TerminateProcess;
DWORD arg_TerminateProcess_address;

BYTE instr_push_SleepTime;
DWORD arg_SleepTime;

WORD instr_call_Sleep;
DWORD arg_Sleep_address;

BYTE instr_push_FilePath;
DWORD arg_FilePath;

WORD instr_call_DeleteFileA;
DWORD arg_DeleteFileA_address;

BYTE instr_push_ThreadID;
DWORD arg_ThreadID;

WORD instr_call_ExitThread;
DWORD arg_ExitThread_address;

DWORD addr_OpenProcess;
DWORD addr_TerminateProcess;
DWORD addr_Sleep;
DWORD addr_DeleteFileA;
DWORD addr_ExitThread;
char addr_FilePath[ 256 ];
};

void CSelfDeleteDlg::OnBnClickedButtonDelete()
{
HANDLE hSnapshot;
PROCESSENTRY32 pe = { sizeof( PROCESSENTRY32 ) };
if ( ( hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ) ) == INVALID_HANDLE_VALUE )
{
 __ERROR__();
 return;
}
if ( !Process32First( hSnapshot, &pe ) )
{
 __ERROR__();
 CloseHandle( hSnapshot );
 return;
}
HANDLE hProcess;
char *p_mem;
CODESTRUCT code;

// push pid
code.instr_push_CurrentProcessPID = 0x68;
code.arg_CurrentProcessPID = GetCurrentProcessId();

// push FALSE
code.instr_push_InheritHandle = 0x68;
code.arg_InheriteHandle = FALSE;

// push PROCESS_TERMINATE
code.instr_push_TerminateProcessRight = 0x68;
code.arg_TerminateProcessRight = PROCESS_TERMINATE;

// call OpenProcess
code.instr_call_OpenProcess = 0x15ff;
// code.arg_OpenProcess_address - must be set after memory allocation

// push 0
code.instr_push_CurrentProcessExitCode = 0x68;
code.arg_CurrentProcessExitCode = 0;

// push eax // that is current process handle
code.instr_push_CurrentProcessHandle_by_eax = 0x50;

// call TerminateProcess
code.instr_call_TerminateProcess = 0x15ff;
// code.arg_TerminateProcess_address - must be set after memory allocation

// push SleepTime
code.instr_push_SleepTime = 0x68;
code.arg_SleepTime = 0;

// call Sleep
code.instr_call_Sleep = 0x15ff;
// code.arg_Sleep_address - must be set after memory allocation;

// push FilePath
code.instr_push_FilePath = 0x68;
// code.arg_FilePath - must be set after memory allocation

// call DeleteFileA
code.instr_call_DeleteFileA = 0x15ff;
// code.arg_DeleteFileA_address - must be set after memory allocation

// push 0
code.instr_push_ThreadID = 0x68;
code.arg_ThreadID = 0;

// call ExitThread
code.instr_call_ExitThread = 0x15ff;
// code.arg_ExitThread_address - must be set after memory allocation;

code.addr_OpenProcess = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "OpenProcess" );
code.addr_TerminateProcess = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "TerminateProcess" );
code.addr_Sleep = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "Sleep" );
code.addr_DeleteFileA = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "DeleteFileA" );
code.addr_ExitThread = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "ExitThread" );;
GetModuleFileName( GetModuleHandle( NULL ), code.addr_FilePath, 256 );

while ( true )
{
 if ( ( hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pe.th32ProcessID ) ) )
 {
  if ( ( p_mem = (char*)VirtualAllocEx( hProcess, NULL, sizeof( CODESTRUCT ), MEM_COMMIT, PAGE_EXECUTE_READWRITE ) ) )
  {
   code.arg_OpenProcess_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_OpenProcess );
   code.arg_TerminateProcess_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_TerminateProcess );
   code.arg_Sleep_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_Sleep );
   code.arg_DeleteFileA_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_DeleteFileA );
   code.arg_ExitThread_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_ExitThread );
   code.arg_FilePath = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_FilePath );
   if ( WriteProcessMemory( hProcess, p_mem, &code, sizeof( CODESTRUCT ), NULL ) )
   {
    DWORD tid;
    HANDLE hRemThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)p_mem, NULL, 0, &tid );
    if ( hRemThread )
    {
     CloseHandle( hSnapshot );
     return;
    }
   }
  }
 }
 if ( !Process32Next( hSnapshot, &pe ) )
 {
  __ERROR__();
  CloseHandle( hSnapshot );
  break;
 }
}
}


 
Yozh_Programmer ©   (2004-04-09 19:07) [216]

Блин очень прошу не стирать вот нормальный код, гадеюсь сейчас все будет ОК!!! Если нет - модераторы вам и карты в руки!!!


#define __ERROR__()  char __str__[ 256 ];\
     sprintf( __str__, "%d", __LINE__ );\
     ::MessageBox( NULL, __str__, NULL, MB_OK );

/*
   push curprocpid
push 0
push PROCESS_TERMINATE
call OpenProcess

   push 0
push eax
call TerminateProcess

push sleeptime
call Sleep

push exename
call DeleteFileA

push 0
call ExitThread
*/

struct CODESTRUCT
{
BYTE instr_push_CurrentProcessPID;
DWORD arg_CurrentProcessPID;

BYTE instr_push_InheritHandle;
DWORD arg_InheriteHandle;

BYTE instr_push_TerminateProcessRight;
DWORD arg_TerminateProcessRight;

WORD instr_call_OpenProcess;
DWORD arg_OpenProcess_address;

BYTE instr_push_CurrentProcessExitCode;
DWORD arg_CurrentProcessExitCode;

BYTE instr_push_CurrentProcessHandle_by_eax;

WORD instr_call_TerminateProcess;
DWORD arg_TerminateProcess_address;

BYTE instr_push_SleepTime;
DWORD arg_SleepTime;

WORD instr_call_Sleep;
DWORD arg_Sleep_address;

BYTE instr_push_FilePath;
DWORD arg_FilePath;

WORD instr_call_DeleteFileA;
DWORD arg_DeleteFileA_address;

BYTE instr_push_ThreadID;
DWORD arg_ThreadID;

WORD instr_call_ExitThread;
DWORD arg_ExitThread_address;

DWORD addr_OpenProcess;
DWORD addr_TerminateProcess;
DWORD addr_Sleep;
DWORD addr_DeleteFileA;
DWORD addr_ExitThread;
char addr_FilePath[ 256 ];
};

void CSelfDeleteDlg::OnBnClickedButtonDelete()
{
HANDLE hSnapshot;
PROCESSENTRY32 pe = { sizeof( PROCESSENTRY32 ) };
if ( ( hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ) ) == INVALID_HANDLE_VALUE )
{
 __ERROR__();
 return;
}
if ( !Process32First( hSnapshot, &pe ) )
{
 __ERROR__();
 CloseHandle( hSnapshot );
 return;
}
HANDLE hProcess;
char *p_mem;
CODESTRUCT code;

// push pid
code.instr_push_CurrentProcessPID = 0x68;
code.arg_CurrentProcessPID = GetCurrentProcessId();

// push FALSE
code.instr_push_InheritHandle = 0x68;
code.arg_InheriteHandle = FALSE;

// push PROCESS_TERMINATE
code.instr_push_TerminateProcessRight = 0x68;
code.arg_TerminateProcessRight = PROCESS_TERMINATE;

// call OpenProcess
code.instr_call_OpenProcess = 0x15ff;
// code.arg_OpenProcess_address - must be set after memory allocation

// push 0
code.instr_push_CurrentProcessExitCode = 0x68;
code.arg_CurrentProcessExitCode = 0;

// push eax // that is current process handle
code.instr_push_CurrentProcessHandle_by_eax = 0x50;

// call TerminateProcess
code.instr_call_TerminateProcess = 0x15ff;
// code.arg_TerminateProcess_address - must be set after memory allocation

// push SleepTime
code.instr_push_SleepTime = 0x68;
code.arg_SleepTime = 0;

// call Sleep
code.instr_call_Sleep = 0x15ff;
// code.arg_Sleep_address - must be set after memory allocation;

// push FilePath
code.instr_push_FilePath = 0x68;
// code.arg_FilePath - must be set after memory allocation

// call DeleteFileA
code.instr_call_DeleteFileA = 0x15ff;
// code.arg_DeleteFileA_address - must be set after memory allocation

// push 0
code.instr_push_ThreadID = 0x68;
code.arg_ThreadID = 0;

// call ExitThread
code.instr_call_ExitThread = 0x15ff;
// code.arg_ExitThread_address - must be set after memory allocation;

code.addr_OpenProcess = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "OpenProcess" );
code.addr_TerminateProcess = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "TerminateProcess" );
code.addr_Sleep = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "Sleep" );
code.addr_DeleteFileA = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "DeleteFileA" );
code.addr_ExitThread = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "ExitThread" );;
GetModuleFileName( GetModuleHandle( NULL ), code.addr_FilePath, 256 );

while ( true )
{
 if ( ( hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pe.th32ProcessID ) ) )
 {
  if ( ( p_mem = (char*)VirtualAllocEx( hProcess, NULL, sizeof( CODESTRUCT ), MEM_COMMIT, PAGE_EXECUTE_READWRITE ) ) )
  {
   code.arg_OpenProcess_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_OpenProcess );
   code.arg_TerminateProcess_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_TerminateProcess );
   code.arg_Sleep_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_Sleep );
   code.arg_DeleteFileA_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_DeleteFileA );
   code.arg_ExitThread_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_ExitThread );
   code.arg_FilePath = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_FilePath );
   if ( WriteProcessMemory( hProcess, p_mem, &code, sizeof( CODESTRUCT ), NULL ) )
   {
    DWORD tid;
    HANDLE hRemThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)p_mem, NULL, 0, &tid );
    if ( hRemThread )
    {
     CloseHandle( hSnapshot );
     return;
    }
   }
  }
 }
 if ( !Process32Next( hSnapshot, &pe ) )
 {
  __ERROR__();
  CloseHandle( hSnapshot );
  break;
 }
}
}



 
pasha_golub ©   (2004-04-09 19:08) [217]

Юрий Зотов ©   (09.04.04 18:39) [213]
Да не в свойстве дело. Дело в перевкрытии отрисовки ячейки. Вызывать инхеритед в любом случае нужно, но... Если DefaultDrawing равно тру, то предок отрисует текст ячейки по-своему, иначе оставит без изменений. Так вот, можно сделать так. Пусть предок отрисует это по-своему, мы в наследнике все шо он нарисовал затрем FillRect"om и нарисуем заново. Но зачем? Поэтому я и нашел лазейку.
Нуждно на время вызова инхеритед DefaultDrawing отключить, а потом возобновить прежнее состояние.

Конечно, по-хорошему нужно было наследоваться от TDrawGrid"a и производить манипуляции, но из-за пару-тройки небольших изменений... Не считаю это целесообразным.

Надеюсь так понятно, но суть точно уловил nikkie.


 
Yozh_Programmer ©   (2004-04-09 19:08) [218]

Ой чувствую мне попадет :(((((((


 
Юрий Зотов ©   (2004-04-09 19:08) [219]

> Style ©   (09.04.04 18:00) [207]
> т.е. OldVal := False; // Kill warning
> такого рода "заглушки" не стоит использовать???

Ну почему уж так вот строго - не стоит, да и все? Иногда стоит, иногда не стоит - конкретно по ситуации надо смотреть.

Понимате, компилятор Delphi настолько "умный", что, можно сказать, любой его варнинг (и даже хинт) безошибочно показывает какую-то кривизну кода (иногда - плохой стиль, мешающий ему построить оптимальный код, очень часто - место потенциальной ошибки). Поэтому ВСЕГДА и ОБЯЗАТЕЛЬНО стоит разобраться, почему появилось сообщение, докопаться до его "первопричины" - а потом устранять уже именно причину, а не следствие.

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


 
Style ©   (2004-04-09 19:13) [220]


> нормальная инициализация локальной переменной


ну я просто ее так назвал.. А вообще я всегда стараю сразу инициализировать переменные(естественно которые буду использовать) как вы думаете это правильно? Или может навредить?


 
Игорь Шевченко ©   (2004-04-09 19:31) [221]


>а совершенно нормальная инициализация локальной переменной


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

OldVal := false; //Make compiler happy (TODO:)

И, Паша, еще совет, обзови ее по-другому, это переменную, например, SavedDefaultDrawing, самому потом понятнее будет, где, зачем и почему она используется.


 
Юрий Зотов ©   (2004-04-09 19:38) [222]

> pasha_golub ©   (09.04.04 19:08) [217]

Паш, не трать время на объяснения азбуки, все это сразу же было и так понятно из твоего кода. Ты лучше о другом задумайся и ответь сам себе на 2 простых вопроса.

1. Вот ты пишешь: "Нужно на время вызова инхеритед DefaultDrawing отключить, а потом возобновить прежнее состояние". А скажи - ЗАЧЕМ восстанавливать прежнее состояние? На что оно вообще влияет? На отрисовку, больше ни на что. И какое оно там будет МЕЖДУ отрисовками - без разницы. А отрисовка у тебя СВОЯ, и она все рулит сама. Вот попробуй - убери восстановление прежнего состояния и проверь, будет ли работать точно также, если WordBreak=True, а DefaultDrawing всегда False, без всяких восстановлений.

2. Разве установка WordBreak в True не означает АВТОМАТИЧЕСКИ, что надо ставить DefaultDrawing в False (и наоборот?) Означает. Ну так и сделай, чтобы все происходило именно АВТОМАТИЧЕСКИ. Для взаимовлияющих свойств компонентов это не только нормальный и   общепринятый, но и даже, можно сказать, обязательный подход (посмотри, например, как работают связки ParentColor-Color, ParentShowHint-ShowHint и т.п.).

И когда ты на эти два вопроса ответишь - ты САМ придешь именно к тому решению, о котором я сразу и писал. Потому что вот как раз для КОМПОНЕНТА оно и есть самое простое и самое нормальное.


 
Юрий Зотов ©   (2004-04-09 19:53) [223]

> Style ©   (09.04.04 19:13) [220]

> я всегда стараю сразу инициализировать переменные(естественно
> которые буду использовать) как вы думаете это правильно? Или
> может навредить?

Навредить это может разве что в смысле ненужных операций. Вот смотрите сами:
MyVar := 0;
... // что-то, к MyVar не относящееся
if условие then MyVar := 1 else MyVar := 2;

Ну и какой был смысл в обнулении MyVar? Никакого (кстати, о чем компилятор и сообщит).

В других случаях следует помнить вот что:
- глобальные переменные и поля объектов инициализируются нулями автоматически;
- все длинные строки (даже и локальные) автоматически инициализируются пустой строкой;
- все динамические массивы (даже и локальные) автоматически инициализируются NIL"ом.
- прочие локальные переменные автоматически не инициализируются ничем и их надо инициализировать вручную.

Вот из этих правил и исходите.


 
Style ©   (2004-04-10 00:51) [224]


> ... // что-то, к MyVar не относящееся


естественно если MyVar я не использую, значит я его и не инициализирую.

if условие then MyVar := 1 else MyVar := 2;

А здесь в принципе инициализация второй раз проходит поэтому
 MyVar := 0;
не нужен... - да и получится лишний ворнинг.


> Вот из этих правил и исходите.

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


 
jack128 ©   (2004-04-10 01:08) [225]


> OldVal := False; // Kill warning
> такого рода "заглушки" не стоит использовать???

например (код не имеет смысла, это только иллюстрация)

function BoolToStr(b: boolean): string;
begin
 if b then result := "true"
 else result := "false"
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 b1,b: boolean;
 s: string;
begin
 b1 := InputQuery(""," ", s);
 if b1 then b := True;
 if not InputQuery("", "", s) then
   exit;
 if not b1 then b := false;
 ShowMessage(BoolToStr(b));
end; будет варнинг, что b может быть неинициализирована хотя это и не так.. Так что заглушки иногда нужны...


 
Юрий Зотов ©   (2004-04-10 08:12) [226]

> jack128 ©   (10.04.04 01:08) [225]

> код не имеет смысла, это только иллюстрация

> будет варнинг, что b может быть неинициализирована хотя это и
> не так..

И очень хорошо, что будет. Потому что, как и говорилось ранее, он сразу укажет на кривизну в коде, на которую стоит обратить внимание - и выяснить, что "код не имеет смысла".

> Так что заглушки иногда нужны.

Но только не в этом случае. А в ЭТОМ случае надо переписать код так, чтобы смысл у него все же появился.


 
Anatoly Podgoretsky ©   (2004-04-10 08:59) [227]

Нехороший пример - бессмысленный и плохо написаный.
Скажи зачем это

if b1 then b := True;
if not b1 then b := false;

Почему не b := b1?
Зачем вообще первый IF?


 
Soft ©   (2004-04-10 21:18) [228]

Думкин ©   (09.04.04 07:27) [184]
> Soft ©   (08.04.04 18:29) [182]
>Так что советую всем почитать "Смертельный марш"(если есть желающие
> могу выслать), который показывает реальные требования к
> программам.

А можно? Или положить в доступное место?

Эдвард Йордан. Смертельный марш (полное руководство для разработчика программного обеспечения по выживанию в безнадежных проектах), 1997. (222.736 Кб)
http://lib.prm.ru/search.phtml?text=%D1%EC%E5%F0%F2%E5%EB%FC%ED%FB%E9&type=0

http://stratum11.pstu.ac.ru/~leonid/base/dmarch.zip


 
Игорь Шевченко ©   (2004-04-10 21:29) [229]

Soft ©   (10.04.04 21:18)

"Путь камикадзе" одноименного автора как-то коррелируется с этой ссылкой ?


 
jack128 ©   (2004-04-10 22:00) [230]


> А в ЭТОМ случае надо переписать код так, чтобы смысл у него
> все же появился.
Хе..Тот код в катором я наткнулся на этот варнинг в конце концов был переписан под чистую, но я не уверен, что такая "переписка" всегда возможна/целесообразна


> Anatoly Podgoretsky ©   (10.04.04 08:59) [227]

b1 := InputQuery(""," ", s);
if b1 then
begin
 // Представь, что здесь некие вычисления  (КОД1), результатом которых будет b
end;
<КОД2: Здесь некий код который должен выполнятся всегда, так же запоминаются некоторые промежуточные результаты, нужные в КОДЕ3>
if not b1 then
begin
<КОД3 - результат этих вычислений - b>
end;


 
nikkie ©   (2004-04-10 22:13) [231]

>jack128
procedure WarningsMustDie;
 procedure Proc1;
 begin
   // Представь, что здесь некие вычисления  (КОД1),
   // результатом которых будет b
 end;

 procedure Proc2;
 begin
   // КОД2: Здесь некий код который должен выполнятся всегда,
   // так же запоминаются некоторые промежуточные результаты,
   // нужные в КОДЕ3
 end;

 procedure Proc3;
 begin
   // КОД3 - результат этих вычислений - b
 end;

begin
 b1 := InputQuery(""," ", s);
 if b1 then begin
   Proc1;
   Proc2;
 end else begin
   Proc2;
   Proc3;
 end;
end;


 
jack128 ©   (2004-04-10 22:28) [232]


> nikkie ©   (10.04.04 22:13) [231]

А теперь вопрос на засыпку, удаление варнингов - самоцель? Если выделять код в процедуры ТОЛЬКО для удаления варнинга, то мне легче будет заглушку поставить..


 
nikkie ©   (2004-04-10 22:33) [233]

>Если выделять код в процедуры ТОЛЬКО для удаления варнинга
по-моему, код становится более читаемым.

>удаление варнингов - самоцель?
по-моему выше уже объяснили. если за ними не следить, то в конце концов их список разрастается и отловить уже реально полезные варнинги невозможно.


 
pasha_golub ©   (2004-04-11 14:21) [234]

Все прочитал, продолжим во вторник.

2Юрий Зотов
Наверное про свойства Вы правы. Но речь идет о примерах, которые могут появиться в связи с другими случаями. С уважением.


 
Soft ©   (2004-04-11 15:26) [235]

Насколько я понял, все кто говорит о красивом коде по типу личности более ЛСЭ (логико-сенсорный экстраверт) http://www.socionics.dp.ua/p_refer/type_15.htm

Соционика или типизация человеческой личности.
http://delphimaster.net/view/14-1081635133/


 
OlegGashev ©   (2004-04-20 00:26) [236]

По поводу чистоты кода. Для .NET есть хороший инструмент FxCop: http://www.gotdotnet.com/team/fxcop/ Жаль, что подобного нет для Delphi.



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

Текущий архив: 2004.04.11;
Скачать: CL | DM;

Наверх




Память: 1.11 MB
Время: 0.047 c
3-1081943258
xloki
2004-04-14 15:47
2004.04.11
APACHE VS DELPHI!!


14-1081913061
User_OKA
2004-04-14 07:24
2004.04.11
WinXP


3-1081502044
_sulent
2004-04-09 13:14
2004.04.11
Сжатие базы


1-1079975560
555ААА555
2004-03-22 20:12
2004.04.11
Принтер и миллиметры


8-1076286432
Maratus
2004-02-09 03:27
2004.04.11
Прорисовка двигающегося выделения как в графических пакетах