?

Log in

No account? Create an account
WTF code - Книга бревна [entries|archive|friends|userinfo]
Книга бревна

[ картинки | галерея ]

WTF code [Jan. 28th, 2010|11:00 pm]
Книга бревна
[dow |10,120.46]

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

Вот что люди пишут, когда правильно упаковать всё в if-then-else не могут, а воспитание не позволяет употреблять матерные выражения оператор goto:

for( int i = 1 ; i > 0 ; i++ )
{
   switch( i )
   { 
   case 1 :
      // do something-1
      // calculate cond1
      if( cond1 )
         i = -2 ;
      break ;
   case 2 :
      // do something-2
      // calculate cond2
      if( cond2 )
         i = -2 ;
      break ;
   case 3 :
      // do something-3
      // calculate cond3
      if( cond3)
        i = 4 ;
      break ;
   case 4 :
      // do something-4
      break ;
   case 5 :
      // do something-5
      break ;
   default:
      i = -2 ;
   }
}

LinkReply

Comments:
[User Picture]From: q_spoiler
2010-01-29 04:18 am (UTC)

Вот здесь очень забавная статейка на эту тему

http://lurkmore.ru/%D0%98%D0%BD%D0%B4%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9_%D0%BA%D0%BE%D0%B4
(Reply) (Thread)
[User Picture]From: fat_yankey
2010-01-29 04:31 am (UTC)
О, в статье нашёл, оказывается комьюнити по теме есть code_wtf.

А приведёный пример писал китаец, да.
(Reply) (Parent) (Thread)
[User Picture]From: tarkon
2010-01-29 04:22 am (UTC)
Это самая странная машина состояний которую я когда-либо видел.
(Reply) (Thread)
[User Picture]From: fat_yankey
2010-01-29 04:38 am (UTC)
На самом деле это не машина состояний. Код создаёт такую оптическую иллюзию, как будто это машина состояний, но это не она.
(Reply) (Parent) (Thread)
[User Picture]From: fat_yankey
2010-01-29 04:52 am (UTC)
Собственно, если это переписать в нормальном виде, устраняя оптическую иллюзию, выйдет:
//do something-1
//calculate cond1
if( !cond1 )
{
   //do something-2
   //calculate cond2
   if( !cond2 )
   {
      //do something-3
      //calculate cond3
      if( ! cond3 )
      {
         //do something-4
      }
      //do-something-5
   }
}


Edited at 2010-01-29 04:54 am (UTC)
(Reply) (Parent) (Thread)
[User Picture]From: t_s_v
2010-01-29 06:40 am (UTC)
а в самом внутреннем if там разве отрицание должно быть?
вроде надо просто if (cond3) { //do something-4 }
но вообще WTF знатный, дддаааа :))))
(Reply) (Parent) (Thread)
[User Picture]From: t_s_v
2010-01-29 06:53 am (UTC)

точнее даже не так. :))

просто

if (!cond2)
{
//do something-4
//do something-5
}

cond3 может быть и true, и false - без разницы.
(Reply) (Parent) (Thread)
[User Picture]From: fat_yankey
2010-01-29 11:15 am (UTC)

Re: точнее даже не так. :))

Вы неправы. Если cond3 == true, то код после case 4: не выполняется, for инкрементирует i и на следующей итерации идёт непосредственно на case 5:.
(Reply) (Parent) (Thread)
[User Picture]From: t_s_v
2010-01-29 01:10 pm (UTC)

Re: точнее даже не так. :))

Ага. Совсем я запутался в этом WTFе. Ж:))))
(Reply) (Parent) (Thread)
From: (Anonymous)
2010-01-30 05:36 pm (UTC)

Соб-сно а зачем тут goto?

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

Ну да. Совершенно нормальный код получился, по-моему.

А зачем Вы предлагаете использовать здесь goto? Чем вариант http://fat-yankey.livejournal.com/94169.html?thread=2868185#t2868185 лучше?
(Reply) (Parent) (Thread)
[User Picture]From: fat_yankey
2010-01-30 05:55 pm (UTC)

Re: Соб-сно а зачем тут goto?

Чисто для улучшения читаемости.

Достаточно типичная проблема - у нас есть длинный кусок линейного кода, в котором во множестве вызываются системные функции. Результат выполнения нужно проверить на ошибку и, если ошибка, прервать выполнение и перейти к коду обработки ошибок. Если писать через if-then-else количество уровней вложенности равно количеству таких вызовов:
err = do1 () ;
if( !err )
{
   err = do2 () ;
   if( !err )
   {
      err = do3 () ;
      ...
}
if ( err )
{
   handle_errors () ;
}

при небольшом количестве вызовов это ОК, при большом становится трудночитаемо. Вариант
{
   err = do1 () ; if( err ) goto errhandling ;
   err = do2 () ; if( err ) goto errhandling ;
   err = do3 () ; if( err ) goto errhandling ;
   ...
}
errhandling:
if( err )
{
   handle_errors () ;
}

выигрывает в читаемости. Видна основная логика кода и логика обработки ошибок в неё практически не встревает.
(Reply) (Parent) (Thread)
[User Picture]From: declen
2010-01-31 09:01 pm (UTC)

Re: Соб-сно а зачем тут goto?

А try-catch не поддерживается?
Кстати, вас с почином.
Это первый пост в вашем журнале по вашей основной профессии.
(Reply) (Parent) (Thread)
[User Picture]From: fat_yankey
2010-02-02 02:19 am (UTC)

Re: Соб-сно а зачем тут goto?

Этож plain C, так что никаких плюсплюсных штучек, да. А код этот (там ещё 300,000 строчек таких же) так выел мне мозх, что ни о чём другом сейчас не думаю. Вот написал, так вроде полегчало, пар выпустился.
(Reply) (Parent) (Thread)
From: thinker8086
2010-02-10 04:29 pm (UTC)
Дык вообще-то есть мнение, что всё существующее - автоматы, т.е. машины состояний.

Между прочим, часть "системных" багов вылавливать проще именно по причине удобства проектирования с помощью бумажки, которые вскрывают логику переходов между состояниями.

Почему бы и нет?

Конечно, в Вашем примере можно было сэкономить половину строк, да и машина состояний в цикле for - абсурдна, ибо по сути просирает основную идею автоматов.

Но применение автоматов в сложном, нагруженном логически коде - часто более чем оправдано.
(Reply) (Parent) (Thread)
[User Picture]From: thesz
2010-01-29 07:40 am (UTC)
Лучше делать так:
do {
  do1
  if c1 break;
  do2
  if c2 break;
  ...
} while (0);
Когда-то пользовался.
(Reply) (Thread)
[User Picture]From: fat_yankey
2010-01-30 02:18 am (UTC)
Ещё лучше так:

{
   do1 ;
   if( c1 ) goto last ;
   do2 ;
   if( c2 ) goto last ;
   ...
}
last:
   ;


Edited at 2010-01-30 02:20 am (UTC)
(Reply) (Parent) (Thread)
[User Picture]From: thesz
2010-01-30 09:07 am (UTC)
Сие уже goto. ;)
(Reply) (Parent) (Thread)
From: (Anonymous)
2010-02-03 07:25 pm (UTC)

А чем лучше?

Просто тем, что лишний "мнимый цикл" убирается?
(Reply) (Parent) (Thread)
[User Picture]From: fat_yankey
2010-02-04 02:15 am (UTC)

Re: А чем лучше?

Ну да, этим.

Это конечно уже вкусовщина, но... Мнимый цикл создаёт лёгкое претыкание в читаемости. Нужно осознать, что он мнимый и понять зачем так.
(Reply) (Parent) (Thread)
[User Picture]From: kouzdra
2010-01-29 08:05 am (UTC)
Это скорее всего в своей первой жизни было какой-то блоксхемой
(Reply) (Thread)
[User Picture]From: fat_yankey
2010-01-29 11:18 am (UTC)
Разве что в голове писавшего.
(Reply) (Parent) (Thread)
[User Picture]From: kouzdra
2010-01-29 11:48 am (UTC)
Думаю, что как раз на бумажке - с которой тупо срисовано: do-something - квадратики, if- - ромбики условий - цифирки - стрелочки "вбок", порядок отражает расположение блоков в диаграмке - видимо была нарисована строго вертикально.

Ну а -2 - exit


Могу, наверное, даже изобразить.
(Reply) (Parent) (Thread)
[User Picture]From: fat_yankey
2010-01-29 12:01 pm (UTC)
Я просто знаю, что не на бумажке. В этом проекте бумажек не было с 1995 года. А код более поздний, да ещё с напластованиями из разных эпох.

Кроме того, слегка облагороженный для ясности, чтоб чисто сам принцип проиллюстрировать. В реальности там по нескольку if-ов в каждой case клаузе и логика более запутанная. Думаю это облагораживание и наталкивает на мысли о блок-схеме.

(Reply) (Parent) (Thread)
[User Picture]From: vladimir000
2010-01-29 09:01 am (UTC)
Условие цикла замечательное.
(Reply) (Thread)
[User Picture]From: vepr_y
2010-01-29 09:13 am (UTC)
Жесть :-)

Бред сумасшедшего :-)

Switch-case вообще оператор крайне специфицкий...
(Reply) (Thread)
[User Picture]From: citizen_md
2010-02-02 06:24 am (UTC)

Ужасаясь и не веря -

так Вы программист???
(Reply) (Thread)
[User Picture]From: fat_yankey
2010-02-03 03:08 am (UTC)

Re: Ужасаясь и не веря -

Я и сам порой ужасаюсь и не верю.
(Reply) (Parent) (Thread)