1. Си / Говнокод #3136

    +135

    1. 1
    while( (*(curr_pos++) != 0x0a) && ((UINT)curr_pos - (UINT)buffer < (UINT)length) );

    Ищем новую строку

    Запостил: dokonvog, 30 Апреля 2010

    Комментарии (22) RSS

    • WTF 1: 0x0a как признак окончания строки ( зависит от системы, надо использовать '\n')
      WTF 2: операции над указателями - может случится переполнение на 64-бит системе
      WTF 3: postfix operator в сложной строке. Ненадо заставлять программистов зря думать - curr_pos++ должно быть в в теле цикла.
      Ответить
      • а как тут переполнение случится?
        Ответить
        • UINT - 32 бит, указатель - может быть 64, при конвертации - переполнение.
          Ответить
          • Я думал на 64битных инт тоже 64 по умолчанию...
            Ответить
            • Нет. И вообще тут не надо думать, просто если типы разные - значит размеры разные.
              Ответить
            • подавляющее большинство архетиктур (за редким исключением в специализированых областях) LP64. LP64 значит "long and pointer are 64 bit"

              DEC Alpha были наверное последними широко-распростаненными ILP64 системами. Альфы были весьма аскетичными и нативно только 64 бит числа поддерживали. Современные процы как правило еще и 32 бит числа держат, как минимум для оперций с памятью. Регистры как правило 64 бита.

              Просто большенству програм для большенства ситуаций int хватает за глаза и делание его 64 бит только повышает расход памяти и cache footprint. В С конвертация указателя в инт почти никогда не была законной: правило "sizeof(void *) == sizeof(long)" появилось еще в те времена когда "sizeof(int) == 2" было.
              Ответить
              • так если поменять на ULONG, все хорошо будет?
                Ответить
                • да. ну по крайней мере для 32/64 бит систем :D
                  но в данном случае вообще не надо конверсии типов.
                  Ц разрешает арифметику на поинтерах:

                  curr_pos - buffer < length

                  исходя из того что curr_pos и buffer указатели на тот же самый тип, или компилер ругнется. (но если они указывают на разные массивы - молись).
                  Ответить
                  • Не знаю, у меня не хочет char* c интом сравнивать. length это ж не указатель.
                    Ответить
                    • то ли я то ли лыжи.

                      сравнивать поинтер с интом нельзя.

                      но разница двух поинтеров (как выше и написано) она не есть поинтер, она есть ptrdiff_t (из stddef.h вашего компилера). ptrdiff_t как правило лонг со знаком. и его можно сравнивавать и интом.
                      Ответить
                • Поковырялся в мсдне,
                  http://msdn.microsoft.com/en-us/library/3b2e7499.aspx
                  An int and a long are 32-bit values on 64-bit Windows operating systems.

                  http://msdn.microsoft.com/en-us/library/aa384242(VS.85).aspx
                  Надо использовать UINT_PTR
                  Ответить
      • WTF1: но зато ведь будет работать на винде и макоси!
        WTF2: смотря что определено под UINT. Но зато ведь будет работать на 32бит!

        а винда/макось 32 бит - это 95%! Так-то!

        WTF3: дело вкуса
        Ответить
        • А я вот с WTF3 соглашусь. Меня, как паскалиста, воротит при виде сложного выражения, содержащего ++, приходится голову ломать, что в каком порядке и как вычисляется. Особенно в выражении ++i+++++i
          Хотя в данном случае я всё понял.
          Ответить
          • >++i+++++i
            BrainFuck? Изотерические языки мне тоже нравятся.
            Ответить
            • Нет, С-подобные языки пока ещё даже не пытаются стать эзотерическими. А жаль.
              Ответить
        • Ну вот если работает, но не в 100% случаев - это это и называется говнокод.
          Алосо, вот тебе 95% успеха, пользуйся:
          #define return (1/(int)(rand()/0.05/RAND_MAX));return
          Ответить
          • > Ну вот если работает, но не в 100% случаев - это это и называется говнокод.

            То есть всё, что не кроссплатформ - то говнокод? Это вообще-то не так, хотя в глубине души соглашусь :)
            Ответить
            • >То есть всё, что не кроссплатформ - то говнокод?

              В общем да. Конечно, если случаи, когда используются непереносимые компоненты, тогда не говнокод. Но непереносимо писать на переносимом языке - говнокод.
              Ответить
        • Пункт 3 добавляет сложность, не обоснованную сложностью проблемы - следовательно WTF. Вообще, подобные вопросы на собеседованиях очень бесят - если порядок неочевиден, то он должен быть неважен, иначе код просто нужно переписать так, чтобы последовательность выполнения была ясна с первого взгляда.
          Ответить
          • ну порядок как бы не очевиден тем, кто плохо язык знает. поэтому на собеседованиях и спрашивают. незачем абы кого брать
            Ответить
    • WTF. WTF? WTF!
      Ответить

    Добавить комментарий