1. C++ / Говнокод #16061

    +16

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    std::string response;
    ...
    char* result = new char[response.size() + 1];
    memcpy(&result[0], &response.c_str()[0], response.size());
    result[response.size()] = 0;
    return result;

    Сам метод возвращает char * (при этом никто не запрещал использовать непосредственно std::string).

    ЗЫ жаль что весь проект запостить нельзя. Он весь достоин.

    Запостил: h4tr3d, 27 Мая 2014

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

    • > &response.c_str()[0]

      На тот случай, если указатель на массив символов не совпадает с указателем на первый элемент массива. Чтобы познать Дзен, нужно было ещё к void* приведение сделать!
      Ответить
      • ну я написал &response.c_str(), а оно предупреждение выдало, пришлось [0] приписать.
        Ответить
        • взятие адреса не нужно, у c_str() тип и так const char *
          Ответить
        • так это ты афтор этого ГК? Первый аргумент memcpy тоже без квадратных скобок и амперсанда не работал? :)
          4-5 строки вкупе делают то же, что и strcpy.
          Ответить
          • \irony memcpy быстрее, да и не сработает так же, если response будет содержать '\0'
            UPD: а может и сработает http://ideone.com/4PT7Fs
            Ответить
            • Чё-то я в наплетённой мною хуйне сам разобраться не могу %)
              Ответить
            • На первом же нуле си-строка все равно как бы заканчивается, так что не важно, будут скопированы последующие или нет.
              Ответить
              • Будут скопированы либо один нолик через strcpy, либо три через memcpy
                возможно, это имеет смысл в контексте, как, например, два нолика http запросе
                Ответить
                • > два нолика http запросе
                  Ээээ. Это фича каких-то виндовых апи для работы с хттп?

                  А еще в винапишной функции для выбора файла такая фигня была - надо было разделять маски одним ноликом, а в конце поставить два.
                  Ответить
                  • > в винапишной функции для выбора файла такая фигня была
                    Точно! Именно оно :) Сразу всплыл в памяти образ шестого билдера.
                    Ответить
                    • >Сразу всплыл в памяти образ шестого билдера.
                      а у кого-то он на рабочем столе лежит
                      Ответить
                      • > а у кого-то он на рабочем столе лежит
                        а у нас лицензия на работе :-) последний, кто в нем писал, ушел полтора года назад; его говно прикрыли газеткой и обходят за милю :)
                        Ответить
                        • выставить лицензию на авито, может нужна кому.
                          Ответить
                • >два нолика http запросе
                  я знаю только про два перевода строки после заголовка. Про нолики не в курсе.
                  Ответить
                  • > два перевода строки
                    А, точно, сам ведь когда-то через телнет баловался. Значит, где-то еще я на это натыкался, вот и обратил внимание.
                    Ответить
          • >так это ты афтор этого ГК?
            нет, я просто забыл выделить сарказм зеленым.
            >Первый аргумент memcpy тоже без квадратных скобок и амперсанда не работал? :)
            А это для симметрии.
            Ответить
    • > Сам метод возвращает char *
      Ну может быть автору это надо было передать в какую-нибудь сишную функцию?

      Хотя даже если так, то можно было бы хотя бы в std::auto_ptr результат завернуть, чтобы с управлением памятью не париться...
      Ответить
      • >std::auto_ptr
        deprecated собственно, как и остальной код афтора
        Ответить
        • boost::scoped_ptr
          Ответить
          • А я вот так и не дождался boost::unique_ptr. Юзаем boost::interprocess::unique_ptr
            Ответить
            • 11 стандарт не в моде? std::unique_ptr
              Ответить
              • > 11 стандарт не в моде
                Ты не поверишь, но пока нет. У меня двое друзей работают по крестам в джвух разных конторах, и ни там ни там не разрешено юзать с++11. И что-то мне намекает, что не только у них такие ограничения.
                Ответить
                • фу, ретрограды
                  на деле же микрософт так и не осилил стандарт - вот поэтому он и причислен к "экспериментальному"
                  видать, все силы бросили на очередные революционные фичи виндовс для планшетов
                  Ответить
                  • > микрософт так и не осилил стандарт
                    Будем честны, g++ тоже его не допилил: GCC's support for C++11 is still experimental. Хотя, судя по табличке, все фичи окромя GC в g++ реализованы.
                    Ответить
                  • У студии начиная с vs2010 уже есть уникптр. Про весь стандарт конечно молчу.
                    Ответить
                • Это смотря подо что писать. Например какой-нить qt на базе gcc вполне себе уже c++11.
                  Ответить
        • > deprecated
          Это если у тебя есть с++11 или бустятинку разрешают юзать. А если только хардкорные с++98 - то нифига оно не депрекейтед.
          Ответить
          • 98 уже сам по себе депрекейтед. Два раза аж заменен. А в этом году, вероятно, и все три будет.
            Ответить
            • Пока разрабы компиляторов не написали, что старые кресты deprecated - они не deprecated. А они этого никогда не напишут ;) Ну разве что лет так через 20-30.
              Ответить
              • Так ведь в каждом новом стандарте пишут, что предыдущий утратил силу.
                Ответить
      • там весь код свой и нужды в char* вообще нет, т.е. не возбранялось воротать std::string по значению. Да, в проекте C++11
        Ответить
    • чё просто c_str не вернуть?
      Ответить
      • видимо, по той же причине, почему не использовать std::string
        Ответить
      • > чё просто c_str не вернуть
        Потому что std::string сдохнет и c_str начнет указывать на освобожденный буфер?
        Ответить
        • сделать ему strdup и вернуть :)
          Ответить
        • А чё в другой std::string не скопировать, который сдохнет лишь когда именно тебе надо?
          Ответить
          • >А чё в другой std::string не скопировать,
            Вернуть c_str() от локальной std::string и ТУТ ЖЕ скопировать в другой std::string, я правильно тебя понял?
            Ответить
            • Ну разумеется!
              Ответить
              • технически у тебя может всё получиться, но формально локальный объект уже уничтожен, как и то, на что указывает c_str().
                Ответить
      • не делай так :) вообще - тут не нужно стесняться возвращать объект по значению, в любом более менее приличном компиляторе сработает RVO или (в данном случае) NRVO оптимизации.
        Ответить
    • return strdup(response.c_str());


      Fixed?
      Ответить
      • если систроку потом удаляют через delete, то скорее Broken
        Ответить
        • > через delete
          Если массив удаляют через delete без [] - то оно в любом случае broken (с педантичной точки зрения, работать то будет).
          Ответить
      • > Fixed?
        Поведение не идентичное, об этом выше пишет Xom94ok.
        Ответить
        • >Поведение не идентичное,
          А код из говна становится не говном, только при эквивалентной замене? :)
          Ответить
          • > А код из говна становится не говном, только при эквивалентной замене? :)
            Не факт, но над неэквивалентной заменой надо сначала 100 раз подумать. Вдруг она что-то поломает в соседнем модуле?
            Ответить
            • 100 раз думать не обязательно, достаточно увидеть код, который всё это использует, чтобы понять какая "эквивалентность" должна быть.
              Ответить
              • > достаточно увидеть код, который всё это использует
                Жопа в том, что не всегда можно его увидеть. А еще большая жопа в том, что говнофичей этого кода могли воспользоваться. Но это в основном либ касается, а не прог.
                Ответить
                • P.S. А еще есть рефакторингоустойчивый код - достаточно юзать побольше глобалок, писать поменьше функций, и побольше копипасты. Тот кому он достанется - сойдет с ума, прежде чем сможет понять, какое поведение функции ожидаемое, а какое - случайное совпадение. И такой код либо будут аккуратно пилить, стараясь на него не наступать, либо перепишут к хуям (если решатся).
                  Ответить
                  • Вот и правильно, что сойдет с ума ДО попытки рефакторинги. Если бы сошел в процессе, то мог бы получиться еще более устойчивый к изменениям код. А так останется хоть кривенький, но рабочий.
                    Ответить
                  • Смотря каков размер сего творения. Иногда проще уволиться
                    Ответить
                • Понятно, что всегда есть исключения. И если такой код попадает в либы и кто-то начинает пользоваться его незадокументированными фичами багами, то это полнейший ахтунг.
                  Ответить

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