Перейти к содержимому

Как найти ошибку в коде c

  • автор:

Найдите ошибку в коде

Найдите ошибку в коде

Простая задача, но все же требует внимательности, а также знаний в программировании. Итак, я дам вам небольшой кусочек кода, а вы скажите в чем здесь ошибка.

unsigned int i; for (i = 100; i >= 0; --i) printf("%d\n", i);

В этом коде есть две небольшие ошибки, которые вам стоит найти.

Ошибки

Первым делом, стоит обратить внимания на неправильное определения переменной i . Дело в том, что в данном случае оно является неверным. Тип unsigned int говорит о том, что значения этой переменной могут быть только цифры, при чем только положительные цифры без знака минус. Данная запись приводит к тому, что цикл будет выполняться вечно, так как условие всегда будет истинным (true).

Корректный код состоял бы из такого условия i > 0 . Он мог бы вывести все значения, кроме нуля. Цикл завершился бы и тогда мы могли бы после самого цикла прописать еще и вывод 0 . К примеру, у нас бы получилось нечто вроде этого:

unsigned int i; for (i = 100; i > 0; --i) printf("%d\n", i); printf("%d\n", i);

Вторая ошибка намного проще и заключается в том, что мы используем %d вместо того чтобы использовать %u . Поскольку мы выводим числа без минуса, то именно так должно все быть. В итоге у нас получился вот такой код, который верно выводит значения от 100 до 1:

unsigned int i; for (i = 100; i > 0; --i) printf("%u\n", i);

Больше интересных новостей

Задача на логику про туриста на озере

Задача на логику про туриста на озере

Как угадать число от 0 до 100 или математический фокус

Как угадать число от 0 до 100 или математический фокус

Разработать план эвакуации жителей Сан-Франциско

Разработать план эвакуации жителей Сан-Франциско

Взвешивание таблеток

Взвешивание таблеток

Как найти ошибки в коде

Начните с просмотра видео, чтобы познакомиться с принципами эффективной отладки и избежать распространенных ошибок.

Также загляните в наш Твиттер. В одном треде мы разобрали несколько примеров, когда вроде бы рабочий код не проходит тесты на Хекслете. Сам тред можно найти здесь.

Примеры в этой статье написаны на языке JavaScript, но принципы одинаковы для любого языка.

Тесты

Код на Хекслете проверяется с помощью автоматических тестов. Обычно они написаны на том же языке, на котором написан сам код. Общий принцип работы такого вида тестирования довольно прост. Тестируемая программа загружается в память и вызывается с разными параметрами, а тесты следят за тем, чтобы ее поведение соответствовало ожидаемому.

Когда код не проходит тесты, то обычно говорят что тесты упали. В этот момент начинается самое интересное. Необходимо понять, где и почему возникла ошибка. И вывод тестов в этом процессе играет ключевую роль, это главный помощник и проводник. Но необходим опыт, чтобы начать делать правильные выводы из того, что пишут тесты.

В первую очередь нужно классифицировать проблему. Ошибки в тестах можно грубо разделить на две категории:

  • ошибки, которые выдает компилятор или интерпретатор: синтаксическая ошибка, ошибка типизации
  • ошибочные утверждения.

Утверждения

Утверждение — это специальная функция, которая вызывает ваш код с определенными параметрами и проверяет, что он возвращает ожидаемый результат. Например:

assert(isPrime(3)); assert.equal(factorial(3), 6);

Самое важное: если тесты упали на утверждении, это означает, что ваш код как минимум отработал, но его результат не соответствует ожидаемому. Причем часто бывает так, что часть утверждений проходит проверку, то есть код возвращает правильный результат, а часть — нет, обычно в пограничных случаях. В конечном итоге падение теста на утверждении говорит о том, что в коде логическая ошибка.

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

assert.js:89 throw new assert.AssertionError( < ^ AssertionError: 3 == 1 at Object.(test.js:4:8) at Module._compile (module.js:413:34) at loader (/usr/local/lib/node_modules/babel-register/lib/node.js:126:5) at Object.require.extensions.(anonymous function) [as .js] (/usr/local/lib/node_modules/babel-register/lib/node.js:136:7) at Module.load (module.js:357:32) at Function.Module._load (module.js:314:12) at Function.Module.runMain (module.js:447:10) at /usr/local/lib/node_modules/babel-cli/lib/_babel-node.js:161:27 at Object. (/usr/local/lib/node_modules/babel-cli/lib/_babel-node.js:162:7) at Module._compile (module.js:413:34)

Вывод можно разделить на две части:

  • Первая — описание того, что ожидалось от функции и что было получено. В нашем примере это строка AssertionError: 3 == 1 . Читается она следующим образом: «ожидалось, что функция вернет 3, но она вернула 1». Это уже хорошо, но еще хотелось бы увидеть, с какими параметрами была вызвана функция. И в этом нам поможет вторая часть вывода.
  • Вторая часть называется backtrace, она содержит список функций, которые последовательно вызывались в коде. Порядок вывода, чаще всего, обратный: в начале то, что вызывалось последним.
    В первую очередь нужно, начиная с конца, найти первое упоминание функции из файла, который похож на тестовый. Обычно его называние содержит слово test. В примере выше это at Object. (test.js:4:8) . В скобках указана строчка, на которой находится вызов этого утверждения. В данном случае — строчка 4.
    Всё, что теперь остается, это зайти в соответствующий файл и посмотреть то, как вызывалась ваша функция.

Предупреждения компилятора и интерпретатора

Синтаксические ошибки

Самый простой тип ошибок. Такая ошибка говорит о том, что вы ошиблись в синтаксисе. Забыли запятую, скобку и тому подобные вещи. Такие ошибки легко находить и исправлять. Синтаксическая ошибка сопровождается текстом, по которому можно загуглить возможные причины.

Другие ошибки

Большой класс ошибок, которые могут возникать в процессе разработки. В выводе компилятора или интерпретатора всегда присутствует сообщение об ошибке, которое очень важно понять. Проще всего сделать, загуглив текст ошибки. Рекомендуем наш гайд Как искать техническую информацию.

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

Многие из этих ошибок легко исправить с помощью отладочной печати (см. урок Отладочная печать).

Последнее обновление более двух недель назад

Игра: найди ошибку в C++ коде

Игра PVS-Studio: найди ошибку в C++ коде

Авторы анализатора PVS-Studio предлагают вам проверить свою внимательность и развлечься. Попробуйте быстро отыскать баг в фрагменте исходного кода и ткнуть в него мышкой.

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

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

Ограничение в 1 минуту сделано для интереса. Иначе вы, скорее всего, верно найдёте и укажете каждую ошибку, так как фрагменты кода короткие. В любом случае относитесь к этому просто как к игре, а не как к настоящему тестированию программистских навыков у вас или ваших коллег :)

Когда нашли ошибку, выделите её кликом мышки и нажмите кнопку "Ответ". Бывает, что в коде есть сразу несколько мест, куда вы можете "ткнуть" — и ответ зачтётся как правильный. Поясним это на примере.

case FuriHalSubGhzPreset2FSKDev476Async: preset_name = "FuriHalSubGhzPreset2FSKDev476Async"; break; FURI_LOG_E(SUBGHZ_PARSER_TAG, "Unknown preset"); default:

Этот код взят из проекта FlipperZero. Анализатор PVS-Studio сообщает, что часть кода никогда не выполняется: V779 [CWE-561, CERT-MSC12-C] Unreachable code detected. It is possible that an error is present. subghz_i.c 44

Кто-то поспешил и использовал макрос логирования после оператора break. Или это следствие неудачного рефакторинга. В любом случае ошибка очевидна, но вот куда именно ткнуть мышкой – вопрос сложнее.

С одной стороны, в качестве ответа можно выбрать оператор break. Он расположен до макроса FURI_LOG_E и прерывает выполнение оператора switch. Значит, проблема здесь.

С другой стороны, можно выбрать макрос логирования. Ведь это недостижимый код.

Так как же быть? Очень просто. В данном случае правильным ответом будет считаться как выделенный оператор break, так и макрос FURI_LOG_E.

Думаем, правила понятны. Желаем вам удачи: начать игру.

Не забудьте, показать этот Quiz вашим коллегам! Развлекайтесь, и безбажного вам кода!

Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Andrey Karpov. PVS-Studio's challenge: can you spot an error?.

Ошибки и предупреждения компилятора и средств сборки C/C++

Статьи в этом разделе документации объясняют диагностические ошибки и предупреждающие сообщения, созданные компилятором Microsoft C/C++ и средствами сборки.

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

Чтобы получить справку по определенному диагностическом сообщению в Visual Studio, выберите его в окне вывода и нажмите клавишу F1 . Visual Studio открывает страницу документации для этой ошибки, если она существует. Вы также можете использовать средство поиска в верхней части страницы, чтобы найти статьи об определенных ошибках или предупреждениях. Или просмотрите список ошибок и предупреждений по инструменту и введите оглавление на этой странице.

Не все ошибки или предупреждения Visual Studio документируются. Во многих случаях диагностическое сообщение предоставляет все доступные сведения. Если вы приземлились на этой странице при использовании F1 , и вы думаете, что сообщение об ошибке или предупреждении требует дополнительного объяснения, сообщите нам об этом. Вы можете использовать кнопки обратной связи на этой странице, чтобы вызвать проблему документации на GitHub. Если вы считаете, что ошибка или предупреждение неправильно, или вы нашли другую проблему с набором инструментов, сообщите о проблеме продукта на сайте Сообщество разработчиков. Вы также можете отправлять отзывы и вводить ошибки в интегрированной среде разработки. В Visual Studio перейдите в строку меню и выберите "Отправить отзыв о > проблеме" или отправьте предложение с помощью справки > по отправке > отзывов > отправить предложение.

Вы можете найти дополнительную помощь по ошибкам и предупреждениям на форумах Microsoft Learn Q&A . Или найдите номер ошибки или предупреждения на сайте Сообщество разработчиков Visual Studio C++. Вы также можете искать решения в стеке Overflow .

Ссылки на дополнительные справочные материалы и ресурсы сообщества см. в разделе справки и сообщества Visual C++.

В этом разделе

Ошибки и предупреждения BSCMAKE (BKxxxxx)
Ошибки и предупреждения, созданные программой технического обслуживания Microsoft Browse Information Maintenance (BSCMAKE.EXE).

Ошибки и предупреждения командной строки
Ошибки и предупреждения, созданные средствами сборки для проблем с параметрами командной строки.

Предупреждения компилятора C4000 — C5999
Предупреждения о проблемах, обнаруженных компилятором C++ (CL.EXE).

Предупреждения компилятора по версии компилятора
Список предупреждений, представленных каждой версией компилятора.

Ошибки среды выполнения C (Rxxxx)
Ошибки, созданные во время выполнения библиотекой среды выполнения C (CRT).

Ошибки и предупреждения CVTRES (CVTxxxx)
Ошибки и предупреждения, созданные файлом ресурсов Майкрософт для программы преобразования объектов COFF (CVTRES.EXE).

Ошибки вычислителя выражений (CXXxxxx)
Ошибки, созданные отладчиком и средствами диагностика.

Ошибки и предупреждения средств компоновщика (LNKxxx)
Ошибки и предупреждения, созданные компоновщиком и связанными инструментами (LINK.EXE, LIB.EXE, DUMPBIN.EXE, EDI ТБ IN.EXE).

Математические ошибки (Mxxxx)
Ошибки, создаваемые библиотекой математики с плавающей запятой во время выполнения.

Ошибки и предупреждения NMAKE (Uxxxxx)
Ошибки и предупреждения, созданные средством Microsoft makefile (NMAKE.EXE).

Ошибки и предупреждения оптимизации с использованием профилей (PGxxxxx)
Ошибки и предупреждения, созданные средствами оптимизации с помощью профилирования (PGO).

Ошибки и предупреждения сборки проекта (PRJxxxx)
Ошибки и предупреждения, созданные собственной системой сборки проекта C++ в Visual Studio.

Векторизатор и сообщения параллелизатора
Диагностические сообщения, созданные параметрами компилятора векторизатора и параллелизатора оптимизации.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *