Комментарии 115
Жаль, что С++ не входит в ряд моих лучших качеств. Кто-нибудь уже справился с заданием хоть раз?
Судя по Google Analytics — такие есть :-).
Ну я могу сказать, что минимум треть ошибок очень простые (связаны с кривым копипастом или просто опечатками). У меня получилось верно определить 5 из 15, а я никогда ничего не писал на c/c++ и вообще кодером себя не считаю. Думаю настоящий спец легко справится.
Хорошо, когда видишь перед собой тольк кусок кода, размером в двадцать строчек, который на 100% содержит как минимум одну ошибку :) Тогда 5 из 15 весьма неплохо. А если у вас проект на пару сотен тысяч строк? :) Какой тогда будет счет? :)
Речь вроде про данный конкретный тест шла, а не про поиск ошибок в больших проектах в целом.
Возможно, я не совсем понял смысл вашего комментария. Я просто отреагировал на
Эти ошибки взяты из реальных проектов. А очень простыми они кажутся потому, что вы видите 20 строк, которые на 100% содержут ошибку.
Ну я могу сказать, что минимум треть ошибок очень простые
Эти ошибки взяты из реальных проектов. А очень простыми они кажутся потому, что вы видите 20 строк, которые на 100% содержут ошибку.
Аналогично. 6 из 15. Хотя я тоже никогда не писал на C++
Вы на100ящий спец. Поздравляю!
Мой вердикт «Knows something about C++ wickedness» (7 из 15). Что соответствует действительности :)
А задачки интересные!
Ищешь ошибки в работе с указателем, а там просто скобка не в том месте стоит.
Большое спасибо за тест, PVS-Studio!
А задачки интересные!
Ищешь ошибки в работе с указателем, а там просто скобка не в том месте стоит.
Большое спасибо за тест, PVS-Studio!
Задачи больше на внимательность, нежели на знание, но самое то, чтобы с утра размять мозг.
Большая часть задач действительно на внимательность: трудно найти опечатку в куче плохоотформатированного кода. Считаю, что часть таких ошибок (но ни в коем случае не все!) лечится продуманным стилем написания кода.
Часть задач — чистой воды Си, тут внимательностью не обойдешься, надо еще и язык знать.
Я не увидел, есть ли какие-то чисто плюсовые ошибки: вызов виртуального метода в конструкторе, обращение к итератору после erase, etc?
Или в общей массе таких ошибок мало?
Часть задач — чистой воды Си, тут внимательностью не обойдешься, надо еще и язык знать.
Я не увидел, есть ли какие-то чисто плюсовые ошибки: вызов виртуального метода в конструкторе, обращение к итератору после erase, etc?
Или в общей массе таких ошибок мало?
К сожалению, тесты ограничены простыми ошибками. Часто это опечатка и Си++ тут ни при чём. Всякие виртуальные методы, к сожалению, не подходят. Примеры получаются слишком длинными и скучно их переваривать. Не оставлять же в классах только по одной функции где ошибки. :) Тогда сразу понятно где ошибка. А напихаешь лишнего для запутывания — получится простыня. Приходилось выбирать короткие простые фрагменты кода.
А вообще, с разными ошибками можно познакомиться здесь. Тут есть, и виртуальные деструторы и erase.
А вообще, с разными ошибками можно познакомиться здесь. Тут есть, и виртуальные деструторы и erase.
Круто, спасибо!
А нет ли у вас на сайте отображения количества обнаруженных ошибок разного типа? Хотя бы проверенных вами — это позволит вести интересную статистику: где на Си/С++ ошибаются чаще всего.
А нет ли у вас на сайте отображения количества обнаруженных ошибок разного типа? Хотя бы проверенных вами — это позволит вести интересную статистику: где на Си/С++ ошибаются чаще всего.
Есть возвращение reference на локальную переменную.
А на С подобной «игры» нет случайно? (совершенно не понимаю С++)
Комментарием выше пишут, что это и есть Си :-).
Я прошелся по первому десятку — ничего сишного и в помине не было!
Попробовал еще раз целиком. Получил:
Из них 3 ошибки сделал, т.к. были явно плюсовые задания и нужно знать С++, чтобы эти ошибки выявить. Еще одну — промазал (непонятно было, куда щелкать, когда закрывающую скобку не туда поставили).
You have found 8 errors out of 15
Из них 3 ошибки сделал, т.к. были явно плюсовые задания и нужно знать С++, чтобы эти ошибки выявить. Еще одну — промазал (непонятно было, куда щелкать, когда закрывающую скобку не туда поставили).
Там все, что нужно знать из С++ — это то, что
this
является указателем…Указателем на что? Там еще непонятные вещи есть: скажем, оператор new. Откуда мне знать, что free не подойдет в данном случае, а нужен delete?
Да, с закрывающей скобкой я тоже не сразу понял, куда щёлкать. Нажал на != и не угадал.
(удалено)
Классная рекламная компания. Не пишу на С++, но понравился способ донесения информации.
Почему не обрабатывает все варианты? И таких вопросов много. Я выбрал нижний вариант, и это ошибка. Не зная логики нельзя конкретно утверждать, где верно, я думаю подошло бы два варианта.
Почему нельзя? Тут повторное сравнение, а не какая-то сакральная логика.
Тут дело не в повторении, а в консистентности с содержанием блока.
а какая разница, что внутри блока, если в него никогда программа не зайдет?
А может тут 2 ошибки? В первом теле if ошибочна вторая строка и повторное сравнение внизу. Контекста мы не знаем. И логика может быть разная, а не только логика PVS-Studio.
Одна тут ошибка. habrahabr.ru/company/pvs-studio/blog/237219/#comment_7978709
Маловероятно. Мне кажется, это не игра на измышление хитрых контекстов, в которых кажущиеся баги — на самом деле фичине ошибки, все проще :)
Ну, тут же очевидно, что ошибка именно сверху. Хотя, анализатор тоже не отличит верх от низа, так что надо оба варианта учитывать…
Если посмотреть внимательно, то станет ясно, что ошибка именно в первой строке. Кстати, после ответа даётся подробное пояснение. Приведу его ещё раз:
Что-бы ошибка стала заметной, упростим и перепишем код:
Теперь стало видно, что везде, кроме первой строки, соблюдается соответствие между именем константы в условии и именами массивов.
В первом условии, следовало использовать константу sC0Min1Min.
Что-бы ошибка стала заметной, упростим и перепишем код:
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: мне жаль, что анализатор так и не купили, не обижайтесь на нас: протянули пару недель, но так и не решились, еще и не ответили на последний реквест, емнип. Проблема не в вас, ваша презентация на нашем коде была хороша и вы крутые, просто мы поменяли парадигму.
P.S. для ребят из PVS-Studio: мне жаль, что анализатор так и не купили, не обижайтесь на нас: протянули пару недель, но так и не решились, еще и не ответили на последний реквест, емнип. Проблема не в вас, ваша презентация на нашем коде была хороша и вы крутые, просто мы поменяли парадигму.
1) Отсутствие каких-то IDE проверок и подсветки кода — нечестно. В одном из последних примеров, где while вложен в if, любая нормальная IDE должна кричать благим матом на этот код.
2) Идея на 100 баллов, но какой-то галименький сайт с без модного оформления и жирных красивых кнопок «лайк — твит — шер». Вы похоже рассчитываете на вирусный эффект, но, думаю, много недоберете из-за этого.
2) Идея на 100 баллов, но какой-то галименький сайт с без модного оформления и жирных красивых кнопок «лайк — твит — шер». Вы похоже рассчитываете на вирусный эффект, но, думаю, много недоберете из-за этого.
Если опустить неточности теста, то.
Такой результат
Идея хороша, но из 6 задач 3 оказались спорными, не зная контекста однозначно ответить нельзя.особенно когда разговор идет о опечатках, не зная что объявлено вне метода нельзя определить и ответ.
В первом же тесте нашел ошибку — но не догадался, что кликать надо на скобочку…
Попробуйте ещё раз. Тем более, могут попасться другие вопросы. :)
Попробовал еще раз. Похоже, что «других вопросов» попросту слишком мало — 12 из 15 были уже знакомые… Если бы в первом же вопросе не промахнулся мышкой мимо
y
— было бы 15 из 15 :)Пробовал два раза, в первом случае 3 /15, во втором 10/15, причем попались вопросы, которые попадались в первый раз.
И еще, тикающее время меня сильно напрягает.
И еще, тикающее время меня сильно напрягает.
Поддерживаю, я не понимаю ограничения по времени. В любом случае можно лишь раз за прохождение выбрать вариант. Напрягает, когда едва просмотрел блок кода, а осталось секунд 20.
Сделайте кнопку «Сообщить о возможном правильном ответе». В системе есть не все варианты, куда по логике можно нажать.
Выбил 11 из 15, т.е. Ready for real-life C.
Вариант 6 "… by tricking the system" и первый запуск с отключенными скриптами в браузере, при которых ответ сразу высвечивается справа, навел на мысли…
Вариант 6 "… by tricking the system" и первый запуск с отключенными скриптами в браузере, при которых ответ сразу высвечивается справа, навел на мысли…
А на HN ещё не постили?
Кто-то помог. Прошу поддержать голосованием: news.ycombinator.com/item?id=8334616
Странный он у вас, тест…
В выражении
if (memcmp(..., sizeof(smth)==0))
Кликнул на скобку после нуля — засчитали не верным, нужно дескать в == кликать.
Называется «угодай какой символ мы сочли ошибочным».
В выражении
if (memcmp(..., sizeof(smth)==0))
Кликнул на скобку после нуля — засчитали не верным, нужно дескать в == кликать.
Называется «угодай какой символ мы сочли ошибочным».
Да, кстати, этот тест выбивается из ряда тестов, где нужно кликать именно в закрывающую скобочку
Я кликнул и у меня всё получилось. И правильный ответ, именно скобка после ==. Быть может, Вы случайно промахнулись…
Первый раз набрал 8/15, второй раз 13/15. Pedant of C++ — что не соответсвует действительности, на С программировал последний раз несколько лет назад, а на С++ вообще никогда ничего не делал. Задачи действительно больше на внимательность и логику.
Так не честно. Я кликнул на «32», а оно не засчитало
И здесь, кликнул на != null, и не засчиталось. Нужно расширять список допустимых кликов.
Могу с вами согласиться. Но я думаю, что разыменование указателя лучше указывает на ошибку. Признаю, что тесты не идеальны.
Ни фига, не следует соглашаться, ошибка однозначна в этом кейсе: использование до проверки. При чем здесь сама проверка то?
При том, что наличие проверки предполагает, что s может быть NULL. Если бы проверки не было, то первое разыменование ошибкой бы тоже не считалось.
Ну, да, а в задании что нужно найти? Правильно, ошибку. Ошибка в проверке что ли? На какой строчке потенциально упадет приложение (такая формулировка только в рамках этой задачи)? Updated: Только не говорите, что в вашем раскладе это будет «ошибочная проверка на NULL» и ее нужно срочно устранить.
Ну я тут в некотором роде как компилятор рассуждал а не как человек.
Если мы скажем что ошибка в разыменовании, то непонятно на каком основании мы вообще считаем что в функции может быть NULL. Может быть перед ней стоит комментарий, который под страхом смерти запрещает в функцию передавать NULL.
Другое дело сказать что проверка s != NULL ничего на самом деле не проверяет. Это очень легко обосновывается тем, что в первой строке по этому указателю уже обратились, а значит он просто не может быть NULL.
Если же человек считает что она таки может быть NULL, то ему придется уже задуматься и может быть переставить проверкку наверх.
Если мы скажем что ошибка в разыменовании, то непонятно на каком основании мы вообще считаем что в функции может быть NULL. Может быть перед ней стоит комментарий, который под страхом смерти запрещает в функцию передавать NULL.
Другое дело сказать что проверка s != NULL ничего на самом деле не проверяет. Это очень легко обосновывается тем, что в первой строке по этому указателю уже обратились, а значит он просто не может быть 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
неправда же stackoverflow.com/questions/2727834/c-standard-dereferencing-null-pointer-to-get-a-reference
www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232
Даже пара примеров кода есть.
Даже пара примеров кода есть.
Вот это жесть получается. То есть разыменовать можно, но после этого ничего сделать нельзя. Даже в reference сохранить.
www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#453
www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#453
Так ведь число 32 не виновато. Ошибка в типе, к которому приводят переменную d. На всякий случай, ошибкой считается и сдвиг. Если правильным считать многие варианты, то тоже не интересно будет.
Ну тут дело в том, что если бы мы сдвигали на 31 а не на 32, то это был бы уже не undefined behavior, потому я на него и указал.
Результат выражения при сдвиге на другое количество бит может уже быть не тем что ожидали, но для этого уже надо понимать что эта функция вообще должна делать.
Результат выражения при сдвиге на другое количество бит может уже быть не тем что ожидали, но для этого уже надо понимать что эта функция вообще должна делать.
Получил 10 очков из 15. «Ready for real life C++».
Но что меня реально поразило — это трудность отыскания таких ошибок. Одно дело — когда смотришь короткий фрагмент и знаешь, что в нем есть ошибка. Совсем другое дело — когда смотришь файл в пару десятков кБ и не знаешь, есть в нем ошибки или нет.
Авторам однозначный зачет! Только сейчас вы меня убедили, что тратить деньги на статический анализатор кода стоит.
Но что меня реально поразило — это трудность отыскания таких ошибок. Одно дело — когда смотришь короткий фрагмент и знаешь, что в нем есть ошибка. Совсем другое дело — когда смотришь файл в пару десятков кБ и не знаешь, есть в нем ошибки или нет.
Авторам однозначный зачет! Только сейчас вы меня убедили, что тратить деньги на статический анализатор кода стоит.
С четвёртой попытки 15/15. И всё равно заявляют, что я, наверное, устал.
Классный тест IQ для С++ — программеров!
Хотя бы share «на похвастаться» не помешал бы.
Отличная идея для продвижения продукта!
You have found 12 errors out of 15. Ready for real-life C++.
Следующим пуском я нашёл все пятнадцать ошибок, однако у вас слишком жёсткие критерии, где щёлкать, поэтому те же 12.
Следующим пуском я нашёл все пятнадцать ошибок, однако у вас слишком жёсткие критерии, где щёлкать, поэтому те же 12.
Ткнул на ==, так как сравнение sizeof с 0 — это бред. Мне сказали что я не прав. Плохой квиз, негодный. Почините.
Не писав на C++ (но зная что‐то), ухитрился сдать тест на 9/15. Причём, по моему мнению, должно было быть 11/15:
. Поправьте пожалуйста.
Кстати, в этом Quiz идёт нечестное сравнение: я знаю, что ошибка есть, а анализатор нет. Ему труднее :)
Скрытый текст
в одном месте при наличии скобки не в том месте я решил нажать на запятую: было выражение вида
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 проект. Запускаем и ломаем голову над сообщениями. :)
Как вариант. Скачиваем PVS-Studio и open source проект. Запускаем и ломаем голову над сообщениями. :)
Ах, запускался бы ваш продукт на Linux! Обхожусь CppCheck и scan-build.
Напишите нам. Мы заключим контракт, после чего адаптируем ядро (command line версию) анализатора под Ваш конкретный linux и компилятор. В рамках дополнительного контракта можно реализовать какую-то интеграцию со средой разработки и прочие плюшки.
(del)
3/15 + 6 в которых я правильно нашел ошибку, но тыкнул в какой-нибудь соседний символ, например.
А еще у вас ошибки в грамматике по крайней мере в 7-м и 14-м ответах.
А еще у вас ошибки в грамматике по крайней мере в 7-м и 14-м ответах.
Прошу благодарных читателей запостить в твиттер (или аналогичные места) ссылку на описание C++ Quiz. Или использовать для ссылки эту статью на Хабре.
Мы возродили и обновили эту игру!
Играть: Челлендж от анализатора PVS-Studio: насколько вы внимательны?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Давай поиграем в игру