Как стать автором
Обновить

Комментарии 115

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


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

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

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

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

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

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

Что-бы ошибка стала заметной, упростим и перепишем код:
     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.
несправедливость
Вот у вас в 13 примере я кликнул на != NULL имея ввиду как раз то, что имел ввиду анализатор.

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

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

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

В выражении

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

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

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

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

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

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

Поэтому я кликнул на == в первом условии, но увы, меня поняли неверно и не засчитали.
> разыменование нулевого указателя не является неопределённым поведением

неправда же stackoverflow.com/questions/2727834/c-standard-dereferencing-null-pointer-to-get-a-reference
Вот это жесть получается. То есть разыменовать можно, но после этого ничего сделать нельзя. Даже в reference сохранить.

www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#453
Так ведь число 32 не виновато. Ошибка в типе, к которому приводят переменную d. На всякий случай, ошибкой считается и сдвиг. Если правильным считать многие варианты, то тоже не интересно будет.
Ну тут дело в том, что если бы мы сдвигали на 31 а не на 32, то это был бы уже не undefined behavior, потому я на него и указал.

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

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

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

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

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

Кстати, в этом Quiz идёт нечестное сравнение: я знаю, что ошибка есть, а анализатор нет. Ему труднее :)
А как можно это исправить? Добавить примеры без ошибок и вариант ответа «ошибок нет»?
Хорошая идея, между прочим — это сделает тест еще труднее.
В некоторых случаях непонятно куда тыкать, даже если знаешь правильный ответ. Например, ниже ошибка из-за приоритета операторов. Кликнуть нужно по закрывающей скобке после '\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) {
  ....
}
Как-то внезапно для себя набрал 10/15, по пару раз не заметил очевидных ошибок из-за поиска просчетов в логике :)
4 of 15. Does not comprehend the wickedness of C++. Ну еще бы, я на нем только лабы в институте писал) Формулировка не нравится. Я do comprehend the wickedness.
10 из 15. На мой взгляд, много примеров с опечатками и копипастой, облегчает поиск, когда предполагаешь, что искать. Особенно в примерах длинных повторяющихся условий.

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

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