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

    +70

    1. 1
    qDebug() << QString("%1-%2").arg("%1").arg("foo");

    Запостил: LispGovno, 19 Апреля 2014

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

    • Люблю я программиирование.
      Ответить
    • какой неудачный ник для крестов :-)
      Ответить
    • http://govnokod.ru/12111
      Ответить
    • Я конечно плюсану.
      >arg("%1")
      Но зачем? И вообще что за любовь постить на гк не прочитав доки к функции.
      Ответить
      • > Но зачем?
        Ну случайно в аргумент попал процентик ;) Мало ли чего там хочешь вставить в строку.

        > не прочитав доки к функции
        Да там этот момент в жопе описан. Вот все и залетают.

        Но документирована она не в самом первом описании arg'а, а только в arg(const QString &a1, const QString &a2), в доку по которому я естественно никогда не заглядывал...
        Ответить
        • >Мало ли чего там хочешь вставить в строку.
          Если хардкод - кодер сам виноват, если юзер-инпут, то это жопа.
          Но практически любые инпуты всегда нужно валидировать/экранировать.
          Ответить
      • И говно в этой функции всё-таки есть - подставляемые данные потенциально становятся куском формата. Хоть это и документировано, но далекооо не лучшая идея. Формат в питоне, банальный сишный принтф и даже пыховская интерполяция себе такую херню не позволяют...
        Ответить
        • >И говно в этой функции всё-таки есть - подставляемые данные потенциально становятся куском формата.
          ССЗБ, если формируешь строку для формата из данных, полученных извне
          $ [/tmp/123] cat ./test.cpp 
          #include <QString>
          #include <QDebug>
          
          int main() {
                  qDebug() << QString("%1-%2").arg("%1", "foo");
                  return 0;
          }
          $ [/tmp/123] g++ -I/usr/include/qt4/QtCore/ -I/usr/include/qt4/  -lQtCore -L/usr/lib/qt4  ./test.cpp
          $ [/tmp/123] ./a.out 
          "%1-foo"


          [code]
          >>> "a={a} b={b}".format(a="{q}", b="{w}").format(q=1, w=2)
          'a=1 b=2'
          [code]
          Ответить
          • > qDebug() << QString("%1-%2").arg("%1", "foo");
            Дык эта форма очень ограниченная, управление форматом чуть менее чем никакое. Ты не можешь вывести например число с двумя цифрами после запятой и строку.

            А "%1 %2".arg("aaa").arg("bbb") вызывает протечку. В этом и говно.

            > если формируешь строку для формата из данных, полученных извне
            Да где же? С каких пор .arg("хуйня") является частью строки формата? Не ну эта протечка задокументирована, но это один хуй неправильно.
            Ответить
            • > А "%1 %2".arg("aaa").arg("bbb") вызывает протечку.
              Почему?
              Ответить
              • arg возвращает строку, к которой снова применяется arg, но без учета первого arg. То есть в таком случае пользовательский ввод постепенно формирует строку, которая используется в качестве шаблона для форматирования
                Ответить
                • и кутешники похоже не сильно хотят решать проблему - в Qt5 тоже осталость это говно.
                  Эх, запилить чтоли свой format на template variadic...
                  Ответить
          • Говно в самой идее arg'а, а не в реализации: Returns a copy of this string with the lowest numbered place marker replaced by string

            Ну а насчет ССЗБ ты прав. Эту функцию вообще нельзя юзать для случаев сложнее подстановки пачки строк или одного параметра с настройками. Вообще. Даже сраный printf и то безопасней.

            P.S. Для меня эта функция в свое время была первым разочарованием в Qt ;(
            Ответить
            • А какие алтернативы у qt? boost.gui не пилят, гтк - очень сомнительная алтернатива, бубунта явно ставит на qt. Остальные wx-виджеты явно умирают в мучениях. От отсутствия алтернатив и расцветает этот трэш...
              Ответить
              • > А какие алтернативы у qt?
                В том и трабла.

                > От отсутствия алтернатив и расцветает этот трэш
                Да не особо оно и расцветает... Они сейчас на QML по большей части ориентируются.
                Ответить
                • > Они сейчас на QML по большей части ориентируются.
                  Ты так говоришь, как будто это тебя демотивирует. По моему грамотный ход. Не на HTML5 же писать под Кт. Хотя в поставке есть "HTML приложения со своим личным браузером".
                  Ответить
            • > Даже сраный printf и то безопасней.
              +1
              printf("%s", "%s");
              И это вполне грамотная ситуация без последствий.
              Ответить
            • > была первым разочарованием в Qt
              А какие там ещё?
              Ответить
              • Несколько косяков в СУБДшных дровах (для разных баз - разные).

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

                Ужасно лагающий перехват stdin/stdout через QProcess под вендой (может и пофиксили, х.з.).

                Не помню точно чего не хватало, но какие-то методы от виджетов не сделали Q_INVOKABLE, из-за чего их в скрипте (QScriptEngine) не поюзаешь.

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

                Но в целом - либа вполне годная и юзабельная. Да и альтернатив походу нет.
                Ответить
                • QThread
                  А что вместо него лучше использовать? А вообще годно же. Сигналов в него заслал, он обработал и ответил. Что ещё надо?
                  Ответить
                  • Там речь совсем не о том, что вместо него использовать. Там речь о том, как его правильно использовать.

                    > Сигналов в него заслал, он обработал и ответил.
                    Ну-ну. Нук опиши, на кого ты повешаешь обработчики сигналов :)
                    Ответить
                    • В общем кошерный способ - создать потомка QObject, который будет принимать сигналы и мувтутреднуть его в QThread (который не надо сабклассить!). Тогда все норм. Но до этого надо еще додуматься/прочитать...

                      P.S. А в официальном мане эти говнюки советовали сабклассить QThread и перекрывать run() ;)
                      Ответить
                      • Попытка первая: читаем ман, пишем потомка QThread'а и навешиваем сигналы прямо на него. Внезапно замечаем, что сигналы обрабатываются в главном потоке (т.к. объект запиливали в главном), а сам тред болтается где-то в сторонке и нифуя не делает.

                        Попытка вторая: находим в мане функцию moveToThread(), радостно вызываем ее после создания потомка QThread'а и... ловим баги при остановке треда.

                        Попытка третья: читаем статью you are doing it wrong¹, и делаем как описано комментом выше. Профит.

                        [1] http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/
                        Ответить
                      • QRunnable есть же.
                        Ответить
                        • Тогда не было. Ну и это не замена QThread, у них задачи разные.
                          Ответить
    • Опять плюсогавно
      Ответить
    • У нас вчера C++ User Group был
      http://tech.yandex.ru/events/yagosti/cpp-user-group/
      Первый доклад как раз был про грабли Qt. Каждый раз, когда слышаю про qt, уши вянут.
      Ответить
      • > В докладе речь пойдёт о современных подходах к реализации эффективных «конкурентных» контейнеров, а также основных возникающих при этом проблемах
        Привет велосипедистам! Как начало сезона?
        Ответить
        • > Привет велосипедистам!
          Это ты об интеле с их TBB и Cilk? А много ли в стандартной библиотеке конкурентных контейнеров?
          Ответить
          • А хоть раз они тебе пригодились? Давай список задач где они были подходящими и имели неоспоримые преимущества перед другими.
            Ответить
            • не юзал, но одобряю

              во всяком случае, tbb мне понравился (я на него ещё с год назад смотрел). Жаль, что у них профиль именно на эффективные вычисления, хотелось бы ещё и типичный сетевой concurrency видеть.
              Ответить

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