Давай поиграем в игру

    PVS-Studio. Давай поиграем в игру.
    Авторы анализатора PVS-Studio предлагают вам проверить свою внимательность.

    Анализаторы кода работают без устали и умеют находить множество ошибок, которые сложно заметить. Мы отобрали некоторые фрагменты кода, в которых мы выявили ошибки с помощью PVS-Studio. Все фрагменты взяты из известных Open-Source проектов.

    Предлагаем вам посоревноваться с анализаторами в прозорливости и попробовать самостоятельно найти ошибки. Вам будет предложено 15 случайно выбранных заданий. За верный ответ насчитывается одно очко, если он дан в течение 1 минуты. Фрагменты кода короткие, и 1 минута это честное ограничение.


    Рассмотрим пару примеров с ошибками и объясним, как указывать правильный ответ.

    Пример первый. Перед вами следующий код:

    Пример 1

    Здесь ошибка выделена красным. При решении задач этого, конечно, не будет.

    Программист случайно опечатался и вместо индекса 2 написал 3. При движении курсора мышки над кодом будут подсвечиваться различные слова и цифры. Вы должны навести курсор на число 3 и нажать левую кнопку мыши.

    Это будет правильный ответ.

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

    Пример 2

    Размер буфера нужно сравнить с числом 48. Случайно в код затесался лишний оператор sizeof(). В результате, размер буфера сравнивается с размером типа int.

    На мой взгляд, ошибкой является оператор «sizeof», и именно на него надо указать мышкой. Однако, не имея перед глазами весь текст программы, можно рассудить так. Оператор 'sizeof' должен был посчитать размер какого-то буфера, но ему случайно подсунули макрос. Ошибкой является использование «SSL3_MASTER_SECRET_LENGTH».

    Для таких случаев ответ будет засчитан, как верный, независимо от того, выберете вы «sizeof» или «SSL3_MASTER_SECRET_LENGTH».

    А теперь желаем вам удачи. Начать игру.

    P.S. Мы понимаем, что задания не идеальны, не всегда очевидно, куда нужно «ткнуть мышкой», и систему при желании можно обмануть. Просто учтите, что этот раздел сайта создан для развлечения, а не для полноценного тестирования кого-то.
    PVS-Studio
    Static Code Analysis for C, C++, C# and Java

    Comments 114

      +4
      Жаль, что С++ не входит в ряд моих лучших качеств. Кто-нибудь уже справился с заданием хоть раз?
        +3
        Судя по Google Analytics — такие есть :-).
          +6
          Ну я могу сказать, что минимум треть ошибок очень простые (связаны с кривым копипастом или просто опечатками). У меня получилось верно определить 5 из 15, а я никогда ничего не писал на c/c++ и вообще кодером себя не считаю. Думаю настоящий спец легко справится.
            +7
            Хорошо, когда видишь перед собой тольк кусок кода, размером в двадцать строчек, который на 100% содержит как минимум одну ошибку :) Тогда 5 из 15 весьма неплохо. А если у вас проект на пару сотен тысяч строк? :) Какой тогда будет счет? :)
              0
              Речь вроде про данный конкретный тест шла, а не про поиск ошибок в больших проектах в целом.
                +6
                Возможно, я не совсем понял смысл вашего комментария. Я просто отреагировал на
                Ну я могу сказать, что минимум треть ошибок очень простые


                Эти ошибки взяты из реальных проектов. А очень простыми они кажутся потому, что вы видите 20 строк, которые на 100% содержут ошибку.
                  +1
                  Я говорил исключительно про тест. У меня нет ни опыта, ни навыков, чтобы судить о том, насколько сложно или просто искать подобные ошибки в больших проектах.
                    0
                    Если честно, я вообще не понимаю как мой комментарий можно было понять неправильно. Lovesuper спросил про тест — я и ответил про тест. Вы думаете я пишу комментарии на случайные темы? Кто тут в этой ветке хоть что-то писал про поиск ошибок в больших проектах кроме вас — непонятно.
                +1
                Аналогично. 6 из 15. Хотя я тоже никогда не писал на C++
                  0
                  Вы на100ящий спец. Поздравляю!
                +14
                Мой вердикт «Knows something about C++ wickedness» (7 из 15). Что соответствует действительности :)
                А задачки интересные!
                Ищешь ошибки в работе с указателем, а там просто скобка не в том месте стоит.

                Большое спасибо за тест, PVS-Studio!
                  +4
                  Понял в чём ошибка в 7ми вариантах, но в 5 и 10 не догадался, куда стоило правильно кликнуть.
                  В результате только 5 очков =)
                    0
                    О, я тоже двумя правильно нашёл, но неправильно ткнул.
                  +12
                  Задачи больше на внимательность, нежели на знание, но самое то, чтобы с утра размять мозг.
                    +2
                    Большая часть задач действительно на внимательность: трудно найти опечатку в куче плохоотформатированного кода. Считаю, что часть таких ошибок (но ни в коем случае не все!) лечится продуманным стилем написания кода.
                    Часть задач — чистой воды Си, тут внимательностью не обойдешься, надо еще и язык знать.
                    Я не увидел, есть ли какие-то чисто плюсовые ошибки: вызов виртуального метода в конструкторе, обращение к итератору после erase, etc?
                    Или в общей массе таких ошибок мало?
                      +1
                      К сожалению, тесты ограничены простыми ошибками. Часто это опечатка и Си++ тут ни при чём. Всякие виртуальные методы, к сожалению, не подходят. Примеры получаются слишком длинными и скучно их переваривать. Не оставлять же в классах только по одной функции где ошибки. :) Тогда сразу понятно где ошибка. А напихаешь лишнего для запутывания — получится простыня. Приходилось выбирать короткие простые фрагменты кода.

                      А вообще, с разными ошибками можно познакомиться здесь. Тут есть, и виртуальные деструторы и erase.
                        0
                        Круто, спасибо!
                        А нет ли у вас на сайте отображения количества обнаруженных ошибок разного типа? Хотя бы проверенных вами — это позволит вести интересную статистику: где на Си/С++ ошибаются чаще всего.
                          +1
                          Такого нет. К сожалению, чем позже диагностика добавлена, тем меньше её будет, так как меньше проектов проверено с её участием. Так что абсолютное количество, весьма неточный показатель.
                          А так, на данный момент лидируют (по степени убывания): V668, V595, V501, V547, V519.
                        0
                        Есть возвращение reference на локальную переменную.
                        –2
                        А на С подобной «игры» нет случайно? (совершенно не понимаю С++)
                          +3
                          Комментарием выше пишут, что это и есть Си :-).
                            +2
                            Я прошелся по первому десятку — ничего сишного и в помине не было!
                              +1
                              Попробовал еще раз целиком. Получил:
                              You have found 8 errors out of 15

                              Из них 3 ошибки сделал, т.к. были явно плюсовые задания и нужно знать С++, чтобы эти ошибки выявить. Еще одну — промазал (непонятно было, куда щелкать, когда закрывающую скобку не туда поставили).
                                0
                                Там все, что нужно знать из С++ — это то, что this является указателем…
                                  +1
                                  Указателем на что? Там еще непонятные вещи есть: скажем, оператор new. Откуда мне знать, что free не подойдет в данном случае, а нужен delete?
                                    –1
                                    Хм… а там была такая задача? Три раза проходил, ни разу не увидел :)

                                    Да, тут, разумеется, надо знать именно C++

                                    PS this — это указатель на некоторую структуру. Этого достаточно для данного теста.
                                      –3
                                      «PS this — это указатель на некоторую структуру. Этого достаточно для данного теста.»
                                      Не на некоторую, а конкретно на ту, чей метод был вызван.
                                        0
                                        Этого уже не важно. Мы ведь все равно не видим объявления этих структур.
                                  +1
                                  Да, с закрывающей скобкой я тоже не сразу понял, куда щёлкать. Нажал на != и не угадал.
                              0
                              (удалено)
                                +1
                                Ошибка в знаке '=', а не в TRUE. Хотя TRUE тоже не очень верно. Следует писать x != FALSE. Но всё равно, здесь однозначно самое плохое, это присваивание.
                                +10
                                Классная рекламная компания. Не пишу на С++, но понравился способ донесения информации.
                                  0
                                  Кампания, простите.
                                  +18
                                  Почему не обрабатывает все варианты? И таких вопросов много. Я выбрал нижний вариант, и это ошибка. Не зная логики нельзя конкретно утверждать, где верно, я думаю подошло бы два варианта.
                                  image
                                    0
                                    Почему нельзя? Тут повторное сравнение, а не какая-то сакральная логика.
                                      +3
                                      Тут дело не в повторении, а в консистентности с содержанием блока.
                                        –1
                                        а какая разница, что внутри блока, если в него никогда программа не зайдет?
                                          +1
                                          А может тут 2 ошибки? В первом теле if ошибочна вторая строка и повторное сравнение внизу. Контекста мы не знаем. И логика может быть разная, а не только логика PVS-Studio.
                                            +1
                                              0
                                              Смею предположить, AxisPod это видит, но там можно выдумать и другие контексты.
                                                0
                                                Вы сами же на свой комментарий и ответили, да, я его видел. Вы сами написали, что ошибка в 1й строке, но вот в каком её месте, почему именно константа неправильна? Почему верны действия внутри тела первого if? В итоге точно утверждать мы можем только одно, что ошибка там есть, но какая конкретно?
                                                +1
                                                Маловероятно. Мне кажется, это не игра на измышление хитрых контекстов, в которых кажущиеся баги — на самом деле фичине ошибки, все проще :)
                                              0
                                              Ну, тут же очевидно, что ошибка именно сверху. Хотя, анализатор тоже не отличит верх от низа, так что надо оба варианта учитывать…
                                                +7
                                                Если посмотреть внимательно, то станет ясно, что ошибка именно в первой строке. Кстати, после ответа даётся подробное пояснение. Приведу его ещё раз:

                                                Что-бы ошибка стала заметной, упростим и перепишем код:
                                                     if (a & Min_Max) { Min[0] Min[1] }
                                                else if (a & Max_Min) { Max[0] Min[1] }
                                                else if (a & Max_Max) { Max[0] Max[1] }
                                                else if (a & Min_Max) { Min[0] Max[1] }
                                                

                                                Теперь стало видно, что везде, кроме первой строки, соблюдается соответствие между именем константы в условии и именами массивов.
                                                В первом условии, следовало использовать константу sC0Min1Min.
                                                +2
                                                несправедливость
                                                Вот у вас в 13 примере я кликнул на != NULL имея ввиду как раз то, что имел ввиду анализатор.

                                                А в целом «Ready for real life C++»(10 из 15) для студента наверное не так плохо)
                                                Думаю для людей, кто внимательно изучает ваши статьи поиск подобных ошибок, даже не встречавшись с ними никогда становится проще.
                                                  +2
                                                  Согласен. Выбил 11 из 15, но на плюсах никогда не писал (delphi, c#), зато прочитал и помню наизусть все посты про PVS-Studio.

                                                  P.S. для ребят из PVS-Studio: мне жаль, что анализатор так и не купили, не обижайтесь на нас: протянули пару недель, но так и не решились, еще и не ответили на последний реквест, емнип. Проблема не в вас, ваша презентация на нашем коде была хороша и вы крутые, просто мы поменяли парадигму.
                                                  –14
                                                  1) Отсутствие каких-то IDE проверок и подсветки кода — нечестно. В одном из последних примеров, где while вложен в if, любая нормальная IDE должна кричать благим матом на этот код.

                                                  2) Идея на 100 баллов, но какой-то галименький сайт с без модного оформления и жирных красивых кнопок «лайк — твит — шер». Вы похоже рассчитываете на вирусный эффект, но, думаю, много недоберете из-за этого.
                                                    +1
                                                    Если опустить неточности теста, то.
                                                    Такой результат
                                                    image
                                                      –1
                                                      Назовите хотя бы одну «неточность» теста, пожалуйста.
                                                      +1
                                                      Идея хороша, но из 6 задач 3 оказались спорными, не зная контекста однозначно ответить нельзя.особенно когда разговор идет о опечатках, не зная что объявлено вне метода нельзя определить и ответ.
                                                        +4
                                                        В первом же тесте нашел ошибку — но не догадался, что кликать надо на скобочку…
                                                          +1
                                                          Попробуйте ещё раз. Тем более, могут попасться другие вопросы. :)
                                                            0
                                                            Попробовал еще раз. Похоже, что «других вопросов» попросту слишком мало — 12 из 15 были уже знакомые… Если бы в первом же вопросе не промахнулся мышкой мимо y — было бы 15 из 15 :)
                                                              0
                                                              Всего их 31.
                                                              +1
                                                              Пробовал два раза, в первом случае 3 /15, во втором 10/15, причем попались вопросы, которые попадались в первый раз.
                                                              И еще, тикающее время меня сильно напрягает.
                                                                0
                                                                Поддерживаю, я не понимаю ограничения по времени. В любом случае можно лишь раз за прохождение выбрать вариант. Напрягает, когда едва просмотрел блок кода, а осталось секунд 20.
                                                                  +6
                                                                  Позвольте, но сколько раз в комментариях люди писали, что эти ошибки — легче легкого найти за 5 секунд!
                                                                    0
                                                                    Тогда мотивация понятно, спасибо.
                                                            +1
                                                            Сделайте кнопку «Сообщить о возможном правильном ответе». В системе есть не все варианты, куда по логике можно нажать.
                                                              +4
                                                              Выбил 11 из 15, т.е. Ready for real-life C.
                                                              Вариант 6 "… by tricking the system" и первый запуск с отключенными скриптами в браузере, при которых ответ сразу высвечивается справа, навел на мысли…
                                                                0
                                                                А на HN ещё не постили?
                                                                0
                                                                Странный он у вас, тест…

                                                                В выражении

                                                                if (memcmp(..., sizeof(smth)==0))

                                                                Кликнул на скобку после нуля — засчитали не верным, нужно дескать в == кликать.
                                                                Называется «угодай какой символ мы сочли ошибочным».
                                                                  +1
                                                                  Да, кстати, этот тест выбивается из ряда тестов, где нужно кликать именно в закрывающую скобочку
                                                                    0
                                                                    Ну это вопрос того, как интерпретировать. По мне — там скобка не на своём месте, а кто то может считать что знак сравнения не там. Оба утверждения верны.
                                                                    0
                                                                    Я кликнул и у меня всё получилось. И правильный ответ, именно скобка после ==. Быть может, Вы случайно промахнулись…
                                                                      0
                                                                      Возможно… Я с телефона, с тач скрина не так порой точно пропадаешь
                                                                        +2
                                                                        Если честно, под мобильные устройство сайт совсем не рассчитан. :(
                                                                    –3
                                                                    Первый раз набрал 8/15, второй раз 13/15. Pedant of C++ — что не соответсвует действительности, на С программировал последний раз несколько лет назад, а на С++ вообще никогда ничего не делал. Задачи действительно больше на внимательность и логику.
                                                                      +3
                                                                      Так не честно. Я кликнул на «32», а оно не засчитало
                                                                      image
                                                                        +3
                                                                        И здесь, кликнул на != null, и не засчиталось. Нужно расширять список допустимых кликов.image
                                                                          0
                                                                          Могу с вами согласиться. Но я думаю, что разыменование указателя лучше указывает на ошибку. Признаю, что тесты не идеальны.
                                                                            0
                                                                            Ни фига, не следует соглашаться, ошибка однозначна в этом кейсе: использование до проверки. При чем здесь сама проверка то?
                                                                              0
                                                                              При том, что наличие проверки предполагает, что s может быть NULL. Если бы проверки не было, то первое разыменование ошибкой бы тоже не считалось.
                                                                                0
                                                                                Ну, да, а в задании что нужно найти? Правильно, ошибку. Ошибка в проверке что ли? На какой строчке потенциально упадет приложение (такая формулировка только в рамках этой задачи)? Updated: Только не говорите, что в вашем раскладе это будет «ошибочная проверка на NULL» и ее нужно срочно устранить.
                                                                                  0
                                                                                  Ну я тут в некотором роде как компилятор рассуждал а не как человек.

                                                                                  Если мы скажем что ошибка в разыменовании, то непонятно на каком основании мы вообще считаем что в функции может быть NULL. Может быть перед ней стоит комментарий, который под страхом смерти запрещает в функцию передавать NULL.

                                                                                  Другое дело сказать что проверка s != NULL ничего на самом деле не проверяет. Это очень легко обосновывается тем, что в первой строке по этому указателю уже обратились, а значит он просто не может быть NULL.

                                                                                  Если же человек считает что она таки может быть NULL, то ему придется уже задуматься и может быть переставить проверкку наверх.
                                                                                    0
                                                                                    Когда в задаче была неправильно (не на то место) поставлена скобка, то ошибкой считалась именно эта скобка (которую нужно всего лишь переставить). В данном случае не на месте (слишком поздно) находится проверка на NULL. Почему же ошибкой считается другой, совершенно правильный оператор?
                                                                                    Да, здесь ошибочная проверка на NULL, в этом месте ей быть не следует, её срочно надо переставить в начало функции.
                                                                                      0
                                                                                      С точки зрения компилятора и работы redundant null check optimization сомнительна именно проверка на null уже после индирекции, потому что она будет optimized out, но при передаче в функцию живого указателя это не вызовет проблем.

                                                                                      Но если в функцию был передан нулевой указатель (именно в этом случае идёт расхождение в работе оптимизированный и неоптимизированной версий), в месте использования результата индирекции через него начинается неопределённое поведение. Так что проблема вызывается именно использованием потенциально неверного указателя, а не поздней его проверкой.
                                                                                0
                                                                                По стандарту разыменование нулевого указателя не является неопределённым поведением. Неопределённым поведением является использование результата такой операции.

                                                                                Поэтому я кликнул на == в первом условии, но увы, меня поняли неверно и не засчитали.
                                                                            +4
                                                                            Так ведь число 32 не виновато. Ошибка в типе, к которому приводят переменную d. На всякий случай, ошибкой считается и сдвиг. Если правильным считать многие варианты, то тоже не интересно будет.
                                                                              +2
                                                                              Ну тут дело в том, что если бы мы сдвигали на 31 а не на 32, то это был бы уже не undefined behavior, потому я на него и указал.

                                                                              Результат выражения при сдвиге на другое количество бит может уже быть не тем что ожидали, но для этого уже надо понимать что эта функция вообще должна делать.
                                                                                +2
                                                                                А что в ней непонятного. :) Формируем 64-битное число из двух 32-битных. И надо сдвигать именно на 32.
                                                                                  +1
                                                                                  За 60 секунд отведенного времени это не так очевидно ;)
                                                                                  Я тоже щелкнул на 32.
                                                                            +9
                                                                            Получил 10 очков из 15. «Ready for real life C++».

                                                                            Но что меня реально поразило — это трудность отыскания таких ошибок. Одно дело — когда смотришь короткий фрагмент и знаешь, что в нем есть ошибка. Совсем другое дело — когда смотришь файл в пару десятков кБ и не знаешь, есть в нем ошибки или нет.

                                                                            Авторам однозначный зачет! Только сейчас вы меня убедили, что тратить деньги на статический анализатор кода стоит.
                                                                              +10
                                                                              Только сейчас вы меня убедили, что тратить деньги на статический анализатор кода стоит.

                                                                              image
                                                                              –2
                                                                              С четвёртой попытки 15/15. И всё равно заявляют, что я, наверное, устал.
                                                                                +2
                                                                                Классный тест IQ для С++ — программеров!
                                                                                  +4
                                                                                  Капча неплохая тоже получится.
                                                                                  –1
                                                                                  Хотя бы share «на похвастаться» не помешал бы.
                                                                                  +2
                                                                                  Отличная идея для продвижения продукта!
                                                                                    0
                                                                                    You have found 12 errors out of 15. Ready for real-life C++.
                                                                                    Следующим пуском я нашёл все пятнадцать ошибок, однако у вас слишком жёсткие критерии, где щёлкать, поэтому те же 12.
                                                                                      –2
                                                                                      imageТкнул на ==, так как сравнение sizeof с 0 — это бред. Мне сказали что я не прав. Плохой квиз, негодный. Почините.
                                                                                        0
                                                                                        Три раза уже про эти закрывающие скобочки писали… или четыре?.. Зачем писать еще раз?
                                                                                          0
                                                                                          Комменты не читай @ Сразу отвечай
                                                                                        0
                                                                                        Не писав на C++ (но зная что‐то), ухитрился сдать тест на 9/15. Причём, по моему мнению, должно было быть 11/15:
                                                                                        Скрытый текст
                                                                                        в одном месте при наличии скобки не в том месте я решил нажать на запятую: было выражение вида if(func(a1, a2), a3), нажата вторая запятая; в другом месте я решил нажать на 32 (имея ввиду, что int бессмысленно так сдвигать), а надо было на type cast или оператор: (unsigned long)d << 32

                                                                                        . Поправьте пожалуйста.

                                                                                        Кстати, в этом Quiz идёт нечестное сравнение: я знаю, что ошибка есть, а анализатор нет. Ему труднее :)
                                                                                          +2
                                                                                          А как можно это исправить? Добавить примеры без ошибок и вариант ответа «ошибок нет»?
                                                                                            0
                                                                                            Хорошая идея, между прочим — это сделает тест еще труднее.
                                                                                          +2
                                                                                          В некоторых случаях непонятно куда тыкать, даже если знаешь правильный ответ. Например, ниже ошибка из-за приоритета операторов. Кликнуть нужно по закрывающей скобке после '\n'.
                                                                                          bool QConfFileSettingsPrivate::readIniLine(....)
                                                                                          {
                                                                                            int dataLen = data.length();
                                                                                            ....
                                                                                            if (i == lineStart + 1) {
                                                                                              char ch;
                                                                                              while (i < dataLen &&
                                                                                                     ((ch = data.at(i) != '\n') && ch != '\r'))
                                                                                                ++i;
                                                                                              lineStart = i;
                                                                                            } else if (!inQuotes) {
                                                                                            ....
                                                                                          }
                                                                                          
                                                                                            0
                                                                                            Как-то внезапно для себя набрал 10/15, по пару раз не заметил очевидных ошибок из-за поиска просчетов в логике :)
                                                                                              0
                                                                                              4 of 15. Does not comprehend the wickedness of C++. Ну еще бы, я на нем только лабы в институте писал) Формулировка не нравится. Я do comprehend the wickedness.
                                                                                                0
                                                                                                10 из 15. На мой взгляд, много примеров с опечатками и копипастой, облегчает поиск, когда предполагаешь, что искать. Особенно в примерах длинных повторяющихся условий.

                                                                                                А не хотите сделать тест с гораздо более интересными ошибками и с бОльшим временем на подумать?

                                                                                                Идея супер! На Эмбеддед Ворлде, кстати, одна из компаний, продвигающих свой анализатор, каждый год устраивает что-то подобное, награждая победителя айпедом :) Только задания у них посложнее :)
                                                                                                  +1
                                                                                                  Думаю, такой тест будет интересен только не многим. Я бы, например, не стал проходить такой тест.
                                                                                                  Как вариант. Скачиваем PVS-Studio и open source проект. Запускаем и ломаем голову над сообщениями. :)
                                                                                                    0
                                                                                                    Ах, запускался бы ваш продукт на Linux! Обхожусь CppCheck и scan-build.
                                                                                                      +2
                                                                                                      Напишите нам. Мы заключим контракт, после чего адаптируем ядро (command line версию) анализатора под Ваш конкретный linux и компилятор. В рамках дополнительного контракта можно реализовать какую-то интеграцию со средой разработки и прочие плюшки.
                                                                                                        0
                                                                                                        Спасибо, возможно однажды воспользуюсь. Я анализаторами пока только балуюсь, сканирую открытые проекты. Вряд ли смогу себе позволить индивидуальную лицензию. В компании нужно убеждать, что проект пригодится.
                                                                                                  0
                                                                                                  (del)
                                                                                                    0
                                                                                                    3/15 + 6 в которых я правильно нашел ошибку, но тыкнул в какой-нибудь соседний символ, например.
                                                                                                    А еще у вас ошибки в грамматике по крайней мере в 7-м и 14-м ответах.
                                                                                                      0
                                                                                                      В некоторых вопросах поди угадай, на что жать надо. Вот
                                                                                                      тут
                                                                                                      image
                                                                                                      например, нажал на знак равенства после ch, пытаясь сказать, что равенство будет не о том — ан нет, скрипт от меня другого символа хотел. Эх.

                                                                                                      Но это так, от чувства обиды — второй запоротый вопрос уже из-за этого. А так — веселая игра, спасибо.
                                                                                                      0
                                                                                                      Прошу благодарных читателей запостить в твиттер (или аналогичные места) ссылку на описание C++ Quiz. Или использовать для ссылки эту статью на Хабре.

                                                                                                      Only users with full accounts can post comments. Log in, please.