Почему студентам нужен анализатор кода CppCat

    CppCat
    CppCat – это простой статический анализатор кода для поиска ошибок в программах на языке Си/Си++. Мы начали выдавать бесплатные академические лицензии всем желающим (студентам, преподавателям и так далее). Для большей популяризации CppCat среди студентов я решил написать эту заметку об ошибках, которые можно найти в лабораторных работах, встречающихся на сайте Pastebin.com.

    Чуть-чуть про CppCat


    CppCat – статический анализатор кода, интегрирующийся в среду Visual Studio и позволяющий найти множество опечаток и прочих ошибок ещё на этапе кодирования. Анализатор умеет запускаться автоматически после компиляции и проверять только что написанный код. Анализатор поддерживает C, C++, C++/CLI, C++/CX.

    О том, как получить бесплатную лицензию на CppCat, описано в статье: Бесплатный CppCat для студентов. Хочу добавить, что мы даём лицензию не только студентам, но и аспирантам, преподавателям и так далее.

    Многих расстраивает, что CppCat не интегрируется в бесплатную среду Visual Studio Express. К сожалению, мы не можем ничего с этим поделать. Express-версии Visual Studio не поддерживают модули расширений (plugins). Однако, это не беда. Хочется напомнить, что студенты имеют доступ к Microsoft DreamSpark и могут получить доступ к Visual Studio Professional.

    Завлечение студентов


    В начале хотел написать что-то в духе:

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

    Потом решил, что как-то это натянуто. Ну какие у студентов серьезные ошибки? Можно и поотлаживать цикл из 10 итераций. Это будет даже полезно. Поэтому я переформулирую рекомендацию использовать CppCat следующим образом:

    Работодатель будет ценить не только ваше умение программировать и писать хитрые алгоритмы. Не менее важно уметь пользоваться базовым инструментарием.

    Грош цена алгоритму, если он будет потерян из-за того, что вы не знаете, что такое система контроля версий и максимум, что предпринимали – делали копию исходных кодов на флешку.

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

    Я не берусь составлять список наиболее важного инструментария. Однако важно знать хотя бы одну систему контроля версий, зачем может быть нужен WinMerge, что такое профайлер, как сделать дистрибутив и так далее.

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

    А теперь то, ради чего мы здесь собрались


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

    Говорить о том, что код часто плох, в этот раз я не буду. И так понятно, что код лабораторных содержит в себе тьму разнообразнейших ошибок. Поэтому я поставил задачу не найти как можно больше ошибок. Это неинтересно. Я попробовал выделить какие-то паттерны ошибок, которые проявляются у студентов чаще всего. Правда, пока я смог четко заметить преобладание ошибок только трех типов. Но про это чуть ниже.

    У Вас может возникнуть вопрос: откуда я взял лабораторные работы? Отвечаю.

    Есть сайт Pastebin.com, где разработчики могут удобно обмениваться фрагментами кода. Студенты активно используют этот сайт. Почти весь код, имеющий тег C++, представляет собой какую-то лабораторную работу или её часть.

    Мы написали программу, которая следит за сайтом Pastebin.com и выкачивает оттуда свежие файлы, помеченные как «код C++». Насобирав более двух тысяч файлов, я сделал из них проект в Visual Studio и проверил его. Больше половины, конечно, проверить не удалось. Во многих файлах только фрагменты кода, вписан текст, не являющийся комментарием, не хватает каких-то библиотек и так далее. Однако я и не ставил целью проверить как можно больше кода, опубликованного на Pastebin.com. То, что проверилось, мне вполне хватит для этой статьи. Сбор файлов продолжается и, возможно, я потом напишу ещё что-то на эту тему.

    Типовые ошибки студентов, изучающих Си++


    Я просмотрел не так уж много ошибок в лабораторных работах. Так что пока могу выделить только 3 паттерна.

    Приводить все подряд примеры ошибок я не буду. Они однотипны и неинтересны. Ограничусь только несколькими примерами. Но, поверьте, если я говорю, что такая ошибка распространена, это действительно так.

    P.S. Многие из опубликованных примеров были с ограничением по времени и уже недоступны. Поэтому ссылки на удалённые страницы давать не буду.

    Паттерн 1. Третье место по популярности. Путаница в однотипных условиях


    Многие задачи по программированию подразумевают проверку многих условий. И, реализуя их, легко запутаться или опечататься. Показательный пример:
    int main()
    {
      int n,a,b,c;
      cin >> n;
      for(int i=0;i<n;i++)
      {
        cin >> a >> b >> c;
        if((a % 2==0 && b % 2 ==0 && c % 2!=0)||
           (a % 2==0 && b % 2!=0 && c % 2==0)||
           (a % 2!=0 && b % 2==0 && c % 2==0)||
           (a % 2!=0 && b % 2 !=0 && c % 2==0)||
           (a % 2==0 && b % 2!=0 && c % 2!=0)||   <<<---
           (a % 2==0 && b % 2!=0 && c % 2!=0))    <<<---
        {
          cout << "1";
        }
        else
          cout << "2";
      }
      cout << endl;
      return 0;
    }

    Предупреждение CppCat: V501 There are identical sub-expressions '(a % 2 == 0 && b % 2 != 0 && c % 2 != 0)' to the left and to the right of the '||' operator. jtzrihcg.cpp 14

    Надо было как-то хитро проверить значения трёх введенных переменных. Скорее всего, код копировался и не везде был правильно поправлен. В результате предпоследняя и последняя строка в условии совпадают.

    Ещё пример:
    int main() {
      ....
      } else if(gesucht < geraten) {
        puts("Ein bisschen zu klein");
      } else if (gesucht < geraten) {
        puts("Ein bisschen zu gross");
      }
      ....
    }

    V517 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error presence. Check lines: 41, 43. wrgkuuzr.cpp 40

    Два раза выполняется проверка (gesucht < geraten), но при этом должны выводиться разные строки.

    Кстати, в обоих примерах ошибка находится в последней строке. Опять нам встретился "эффект последней строки".

    Паттерн 2. Второе место по популярности. Выход за границу массива на 1 элемент


    То, что элементы массивов нумеруются в языке C++ от нуля, является большим затруднением при его изучении. Т.е. вроде понять это просто, но вот научиться не выходить за границу массива очень сложно. Если нужен 10 элемент массива, то так и хочется написать A[10]. Пример:
    int main()
    {
      ....
      int rodnecs[10];
      ....
      VelPol1 = rodnecs[1] + rodnecs[3] + rodnecs[5] +
                rodnecs[8] + rodnecs[10];
      ....
    }

    Предупреждение CppCat: V557 Array overrun is possible. The '10' index is pointing beyond array bound. 0z3x9b3i.cpp 38

    Ещё:
    void main()
    {
      ....
      double pop[3][3];
      ....
      for (int i = 0; i<3; i++)
      {
        calc_y[i] = F(pop[i][1], pop[i][2], pop[i][3], x[i]);
      }
      ....
    }

    Предупреждение CppCat: V557 Array overrun is possible. The '3' index is pointing beyond array bound. 1uj9v9xs.cpp 48

    Много неправильных сравнений в условиях циклов:
    int main()
    {
      int i,pinakas[20],temp,temp2,max,min,sum=0;
      for (i=1;i<=20;i++)
      {
        pinakas[i]=rand();
      ......
    }

    Предупреждение CppCat: V557 Array overrun is possible. The value of 'i' index could reach 20. 287ep6c0.cpp 20

    Очень много:
    int main()
    {
      const int arraySize = 10;
      int a[arraySize];
      int key,index,to_do = arraySize - 1;
      bool did_swap = true;
    
      srand(time(NULL));
      for (int i = 0; i <= arraySize; i++)
      {
        //generating random number between 1 - 100
        a[i] = rand() % 100 + 1;
      }
      ....
    }

    Предупреждение CppCat: V557 Array overrun is possible. The value of 'i' index could reach 10. wgk1lx3u.cpp 18

    Остальные ошибки аналогичны приведённым выше, так что закончим.

    Паттерн 3. Первое место по популярности. Неинициализированные переменные


    О! Я, кажется, понял, почему, кого не спроси, одной из наиболее частых и опасных ошибок в программировании на Си/Си++ люди называют «неинициализированные переменные». Но, при этом, анализируя проекты с помощью PVS-Studio, я редко встречаю эту ошибку.

    Почему? Видимо, при изучении языка все очень сильно набивают себе шишки на этом. Таким образом, программисты потом почти не допускают такие ошибки. Но воспоминания остались. И на вопрос, чего надо бояться, часто ответят «неинициализированные переменные».

    Есть совсем простое:
    int main()
    {
      ....
      int n,k=0, liczba=n, i=1;
      ....
    }

    Предупреждение CppCat: V614 Uninitialized variable 'n' used. 1hvefw6r.cpp 92

    Можно неправильно работать со списком:
    void erase(List * Lista){
      List* pom;
      pom->next = Lista->next;
      Lista->next= pom;
      delete pom;
    }

    Предупреждение CppCat: V614 Uninitialized pointer 'pom' used. 6gpsgjuy.cpp 54

    Можно сделать цикл со случайным количеством итераций:
    void main()
    {
      int i,n;
      imie* ime[20];
      string nazwa;
      string kobieta="Kobiece imina: ";
      wpr_dane();
      for (i = 1; i < n; i++)
      {
        ....
    }

    Предупреждение CppCat: V614 Uninitialized variable 'n' used. 8kns8hyn.cpp 63

    Можно вначале использовать, а потом вводить значение переменной:
    int main() {
      int n1;
      int n2;
      std::vector<int> vec1(n1);
      std::vector<int> vec2(n2);
      std::cin >> n1;
      for (int i = 0; i < n1; i++) {
        std::cin >> vec1[i];
      }
      std::cin >> n2;
      for (int j = 0; j < n2; j++) {
        std::cin >> vec2[j];
      }
      ....
    }

    Предупреждения CppCat:
    • V614 Uninitialized variable 'n1' used. 9r9zdkp6.cpp 25
    • V614 Uninitialized variable 'n2' used. 9r9zdkp6.cpp 26
    Далее приводить примеры, думаю, смысла нет. Но, поверьте, студенты отстреливают себе ноги неинициализированными переменными разнообразнейшими способами.

    Прочие ошибки


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

    Неправильное вычисление размера массивов


    Многим начинающим тяжело даётся понимание, что в Си/Си++ указатель и массив – это разные сущности. В результате нередко попадается код подобный этому:
    int arrayLen(int p[])
    {
       return(sizeof(p)/sizeof(*p));
    }

    Предупреждение CppCat: V511 The sizeof() operator returns size of the pointer, and not of the array, in 'sizeof (p)' expression. seprcjvw.cpp 147

    Правда, функция arrayLen() нигде не используется. Видимо, из-за того, что не работает. :)

    Ещё один пример:
    bool compare_mas(int * mas, int * mas2){
      //вычисляем кол-во элементов первого массива
      const auto mas_size = sizeof(mas) / sizeof(mas[0]);
    
      //вычисляем кол-во элементов второго массива
      const auto mas2_size = sizeof(mas2) / sizeof(mas2[0]);
      ....
    }

    Предупреждения CppCat:
    • V514 Dividing sizeof a pointer 'sizeof (mas)' by another value. There is a probability of logical error presence. 0mxbjwbg.cpp 2
    • V514 Dividing sizeof a pointer 'sizeof (mas2)' by another value. There is a probability of logical error presence. 0mxbjwbg.cpp 3

    Не там поставлена точка с запятой ';'


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

    Типовой пример:
    vector sum(vector m[],int N){
    vector sum,tmp;
        for (int i=0;i<N;i++);
        {
        tmp.a=m[i].a;
        tmp.b=m[i].b;
        tmp.c=m[i].c;
        sum.a+=tmp.a;
        sum.b+=tmp.b;
        sum.c+=tmp.c;
        }
        return sum.a,sum.b,sum.c;
    }

    Предупреждение CppCat: V529 Odd semicolon ';' after 'for' operator. knadcqde.cpp 122

    Досрочное прерывание цикла


    Есть ряд примеров, где цикл случайно прерывается раньше времени:
    int main()
    {
      ....
      for (long long j = sled.size()-1; j > i; j --)
      {
        sled[j] = '0';
        des = 1;
        break;
      }
      ....
    }

    Предупреждение CppCat: V612 An unconditional 'break' within a loop. XHPquVXs.cpp 31

    Неправильная работа с массивами


    В нескольких лабораторных встретилась работа с массивами в стиле Pascal. То есть используется запятая, что хоть и компилируется, но работает, конечно, неправильно:
    void build_maze(){
      // tablica przechowujaca informacje o odwiedzonych polach
      bool ** tablica = new bool *[n];
      ....
      if (tablica[aktualny.x - 1, aktualny.y] == false){
      ....
    }

    Предупреждение CppCat: V520 The comma operator ',' in array index expression '[aktualny.x — 1, aktualny.y]'. qqxjufye.cpp 125

    Или забывают, что память под возвращаемые массивы надо выделять специальным образом:
    int *mul3(int *a)
    {
      int mem = 0;
      int b[1001];
      for (int i = 100; i >= 0; i--)
      {
        int x = a[i] * 3 + mem;
        mem = x / 10;
        b[i] = x % 10;
      }
      return b;
    }

    Предупреждение CppCat: V558 Function returns the pointer to temporary local object: b. hqvgtwvr.cpp 89

    WTF


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

    Приведу целиком один такой пример:
    #include <iostream>
    using namespace std;
    int main()
    {
        int a[10];
        for(int i=0; i<50; i++)
            cout << a[i] << endl;
        //ovoj loop ili kje krashne ili kje ti nedefinirani vrednost
        //(ne mora da bidat 0)
        //ako namesto 50 stavis 500000, skoro sigurno kje krashne
        int b[10];
        for(int i=0; i<50; i++)
        {
            b[i] = i;
            cout << b[i] << endl;
        }
        //ovoj loop nekogas kje raboti, nekogas ne. problemot so
        //out-of-bounds index errori e sto nekogas rabotat kako
        //sto treba, pa greskata tesko se naogja
    }

    Что ещё не вошло статью


    Много что не вошло! Например, встречается неправильное использование функций printf(). Но это настолько банально, что даже писать про это не хочется.

    Впрочем, встречались и достаточно экзотические разновидности ошибок:
    void zmienne1()
    {
      ....
      int a,b,c,d;
      cin >> a >> b >> c >> d;
      if(a == b == c == d)
      ....
    }

    Предупреждение CppCat: V709 Suspicious comparison found: 'a == b == c'. Remember that 'a == b == c' is not e qual to 'a == b && b == c'. b5lt64hj.cpp 284

    Тоже из редкого (если, конечно, не смотреть на предупреждения компилятора):
    const long AVG_PSYCHO = 0.8;
    const long AVG_GRAD = 1.2;

    Предупреждения CppCat:
    • V674 The '0.8' literal of the 'double' type is assigned to a variable of the 'long' type. Consider inspecting the '= 0.8' expression. 2k2bmnpz.cpp 21
    • V674 The '1.2' literal of the 'double' type is assigned to a variable of the 'long' type. Consider inspecting the '= 1.2' expression. 2k2bmnpz.cpp 22
    Тем не менее, надо заканчивать. Надеюсь, я развлек читателей и соблазнил кого-то попробовать CppCat.

    Почему мы не планируем делать какой-либо online-анализатор


    Я предвижу вопрос: «Почему бы вам не сделать какую-то систему для online-проверки кода?». Например, есть какая-то форма, куда можно вставить код и нажать кнопку «проверить». Или, раз вы мониторите сайт pastebin.com, так почему бы не выкладывать куда-то результаты проверки?

    Я уверен, что делать этого нам не нужно. Для этого есть три причины, поэтому прошу не начинать дискуссию на эту тему.

    Причины:
    1. Это не нужно ни нам, ни пользователю. Нам это добавит работы. А пользователь не получит ничего нового. Он может просто скачать и установить PVS-Studio или CppCat и провести все эксперименты, которые пожелает. Демонстрационной версии будет более чем достаточно. Часто формы «вставь и проверь код» делают те, у кого просто так нельзя скачать пробную версию. У нас можно. Более того, она не имеет каких-либо функциональных ограничений. Ещё кто-то может сказать, что у него нет Windows, а он хотел что-то попробовать. Но раз у него нет Windows, то он всё равно не наш пользователь.
    2. Такая система сильно искажает оценку возможностей статического анализатора. Статья на эту тему: Мифы о статическом анализе. Миф пятый – можно составить маленькую программу, чтобы оценить инструмент. Мы хотим, чтобы люди испытывали анализатор на своих реальных проектах, а не на синтетических примерах.
    3. Как уже я сказал, синтетические примеры мы проверять не хотим. А проверить проект целиком сложно с инфраструктурной точки зрения. Подробнее про это написано в интервью. Кратко: придётся делать сложную систему, куда нужно закачивать исходники, библиотеки, настраивать параметры сборки и так далее. Иначе полноценный анализ невозможен. Получается, что проще скачать анализатор, установить и проверить.

    Заключение


    Уважаемые студенты и преподаватели, будем рады видеть вас среди наших пользователей. Желаю студентам стать квалифицированными специалистами и склонить в дальнейшем свой коллектив на приобретение PVS-Studio для командной работы.

    Дополнительные ссылки:


    1. PVS-Studio для Visual C++.
    2. Альтернатива PVS-Studio за $250.
    3. Сравнение возможностей статических анализаторов кода PVS-Studio и CppCat.
    4. Бесплатный CppCat для студентов.

    К сожалению, мы больше не развиваем и не поддерживаем проект CppCat. Вы можете почитать здесь о причинах.
    PVS-Studio
    Static Code Analysis for C, C++, C# and Java

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

      +8
      Студентов хорошо заставлять пользоваться статическим анализатором еще потому, что далеко не все ошибки проявляются во время тестирования. В молодости при переносе и мелкой модификации программы с VAX/VMS на DOS своей сданной и зачтенной программы я наткнулся на массу ошибок в использовании памяти, которые были бы замечены статическим анализатором.
      В те времена я еще думал — «работает, да и ладно». От таких мыслей стоит отучать.
        +3
        Неициализированные переменные компилятор сам отлавливает, разве нет? Не скажу за все, но Студия точно выдаёт warning C4700: uninitialized local variable 'bla bla bla' used. Может поэтому редко встречается?
          0
          И поэтому, думаю, тоже. Однако не панацея. Некоторых (не студентов) какими-то предупреждениями компилятора не оставить. Предупреждения просто не смотрят или отключают.
            +1
            Тогда и CppCat бессилен.
              0
              Это да. :)
              0
              Зря минусуете. Суровая правда жизни. :)
              Некоторые действительно считают предупреждения компилятора недостойными внимания.
                0
                Скорее всего этому студенту программирование совсем не интересно. Такие также не задумываются над форматированием кода, названием переменных и функций.
                  0
                  Вся печать, что я не про студентов говорил, а о «программистах». :( Я в силу своего рода деятельности, бывает такого послушаюсь.
                  Вот, пример, относительно из свежего. Мне один знакомый в icq жаловался после смены работы:

                  да у меня культурный шок… люди игнорируют предупреждения компилятора. сидел исправлял все это. нашел пару ошибок. пытался убедить своего начальника сектора, что Cstyle cast — бяка и надо пользоваться кастами си++… но пока безуспешно

                  на этой неделе привел за ручку начальника отдела и 1 из разработчиков и показывал им предупреждения которые выдает cppcheck. потому что если взять 1 разработчика, то он говорит что это не мой код… а в моём все хорошо :)

                  да, pvs-studio находит ошибки после cppcheck. Но тут бесплатный cppcheck то не приживается. эх…
                  0
                  Дык, такие и минусуют. Очевидно же… )))
                +4
                Более того, нормальные компиляторы уже давно умеют выдавать предупреждения практически по всем описанным в статье нюансам, и это я даже не говорю про компилятор-анализатор clang. Оба компилятора доступны студентам безо всяких унижений.

                Но проще сказать чем сделать — кто из студентов смотрит на предупреждения компилятора, сдавая зачёт в последний день? И кто сказал, что такие студенты начнут пользоваться анализаторами, стыдливо показывая пустую зачётку?:)
                +10
                У студентов самая большая проблема по-началу — неумение читать сообщения об ошибках. Даже однозначные «no such variable 'x' in scope» вводят некоторых в ступор.
                  +2
                  А ещё студенты любят игнорировать warning'и. Сам этим грешил, каюсь… Посоветовал бы студентам включать флаги
                  -Wall -Werror

                  Много чему научат…
                    +7
                    У нас был преподаватель (ПЯВУ, язык Си), который не принимал лабораторные без -Wall -Werror -pedantic =) если бы ещё каждый сам писал лабораторные — больше народу соображало бы.
                      +1
                      Молодец Ваш преподаватель! Все бы так!
                  +5
                  Имхо, студенты должны учиться на своих ошибках, а не халявить с анализаторами кода )
                    +3
                    Чтобы можно было учиться на ошибках, кто-то должен на эти ошибки указать. Предположим, студенты используют memset(), чтобы перезаписать массив, в котором хранился ключ шифрования, а компилятор удалил вызов memset(), потому что смог определить, что этот вызов в именно этом месте, согласно Стандарту, не влияет на так называемое «наблюдаемое поведение» (описано подробно тут). Как вы думаете, насколько реально, что студенты это найдут?
                      +1
                      Если надо готовить не системных программистов, а прикладников, то С++ уже не вариант и проблем таких не будет.
                      Но даже в упомянутом случае, если студент от безысходности полезет в дизассемблер — это ему только в плюс пойдет. Хотя как вариант в случае безысходности, можно и к анализатору прибегнуть.
                      Обходя аккуратно разложенные грабли, мы теряем ценный опыт.
                        +1
                        Чтобы он полез в дизассемблер, он должен сначала пронаблюдать, что «что-то не так», и взяться это исследовать. Например, он заметит, что в конец сохраняемого программой файла каждый раз дописывается один и тот же блок случайных на вид данных. Если программа записывает, например, JPEG, в котором после кодированного изображения можно безболезненно записывать что угодно, он может и полениться выяснять, в чем именно проблема.
                          0
                          Если все работает, он и сообщения анализатора проверять не будет. А с анализатором и в дизассемблер не полезет — зачем — починил — все ОК, ради чего вдаваться в подробности?
                          Понятное дело — можно пользоваться анализаторами и отдельно курс про ошибки пройти с детальным рассмотрением. Но теория обычно плохо усваивается.
                            0
                            Анализатор как раз целенаправленно ищет типовые дефекты, делает это довольно быстро, не устает, обычно выдает хорошо продуманные предупреждения. Запустить анализатор хотя бы из любопытства (кто-то рассказал, что это такая крутая штука, которая в его программе воооот такую ошибку «на ровном месте» нашла, надо попробовать) и увидеть крайне неожиданное сообщение о возможном удалении вызова memset(), по-моему, гораздо реальнее, чем пристально рассмотреть машинный код всей программы и найти последствия удаления вызова.
                              0
                              Вроде про студентов с лабами речь? Там ничего невозможного в плане просмотра машинного кода нет, курсовой еще соглашусь. А за 1-20 лабораторной работы — ну это должен быть очень крутой студент, чтобы столько наваять, но в таком случае он наверное уже и опытный должен быть…
                                0
                                Можно напороться на неопределенное (или определенное :-)) поведение, а в asm увидеть, что написанный тобою код оказался вообще вырезан. Такие случаи и у студентов бывают. Но мне к сожалению не приходилось видеть, чтобы начинающие программисты смотрели в ассемблерный код, чтобы понять, что работает не так.
                                  0
                                  Я не говорил «невозможно». Очень терпеливый студент™, возможно, и найдет, но статический анализатор, скорее всего, сделает это быстрее и надежнее.
                                    0
                                    Разумеется статический анализатор сделает быстрее и надежнее, только экспириенс будет мелкий )
                    • НЛО прилетело и опубликовало эту надпись здесь
                        +3
                        > Express-версии Visual Studio не поддерживают модули расширений (plugins)

                        У них же недавно вышла community версия, которая полностью идентичная pro (http://www.visualstudio.com/products/visual-studio-community-vs)
                          +9
                          С малых лет подсаживаете! Первая доза бесплатно :-)
                            –1
                            Дело в том, что тем, кому нужен статический анализатор обладают в среднем следующими признаками:
                            1. у них маловато опыта
                            2. они еще не знают о существовании подобных инструментов
                            Ну что же, PVS-студио статьями на хабре всячески подталкивает их. С выгодой для себя, но это не в упрек будет сказано.
                            Что лучше — набить себе шишку ища ошибку глазами, получить пистон от учителя за косяки в лабе или использовать инструмент для поиска ошибок — это вопрос даже не спорный, а религиозный. По крайней мере свободу использовать или *не* использовать — не отнять. И это хорошо.
                              +1
                              Дело в том, что тем, кому нужен статический анализатор обладают в среднем следующими признаками:

                              3. Подключаются к разработке уже существующего проекта. Не буду же я перечитывать тысячи строк чужого кода, который никогда ничем не проверялся.
                            +5
                            void main()
                            {
                              ....
                              //evaulation
                              double calc_y[3];
                              for (int i = 0; i<3; i++)
                              {
                                calc_y[i] = F(pop[i][1], pop[i][2], pop[i][3], x[i]);
                              }
                              ....
                            }

                            Здесь явно ругается на pop, а не на calc_y. В статью следовало поместить объявление pop, чтобы было понятно. А на самом деле проблема в том, что предупреждение «V557 Array overrun is possible. The '3' index is pointing beyond array bound» не содержит имени массива, вот вы сами и запутались. Кто-то может подумать, что CppCat ругается на другой массив и решит, что это ложная сработка.
                              0
                              Спасибо. Взял в пример не тот массив. Поправил.
                                +1
                                И вот ещё неправильное предупреждение: V612 An unconditional 'return' within a loop. В том примере, который вы показали, на самом деле unconditional 'break', а не 'return'. Вообще правильная формулировка диагностики очень важна :-)
                                  +1
                                  Не то сообщение скопировал. Поправил.
                                  Вот хороший пример, как исправление ошибки на ранних этапах является более дешёвой операцией. Нет бы мне быть чуть внимательнее и сразу сделать правильно. А теперь мне приходится править текст сразу на нескольких сайтах.
                                  Используйте статический анализ, и вы сэкономите массу времени, сил, а иногда и нервов.
                              +1
                              Не знаю, на сколько в тему, история из жизни.
                              Когда еще не учился в инсте, написал девушке курсач. Затем, уже на 1 курсе в том же институте, по счастливой случайности, у старосты оказался тот же вариант. Я подсуетился, дал старосте курсач, и дошло время до объяснения всего этого безобразия. В курсаче была обработка матриц, простейшие действия над оными, и немного работы с указателями. Так вот каково было мое удивление, когда я запросто выкинул 30-40% кода, потому что не мог объяснить, зачем он был нужен.
                              Все это я к тому — надо знать современные инструменты, с ними гораздо проще разбираться с неизвестными технологиями/языками, и жалко, что студентов к этому не приучают.
                                –1
                                Статический анализатор, это отличный code review и code style guide в одном флаконе. Особенно, в случае если нет рядом более опытного старшего товарища. Для студента с амбициями must have, как говорится…
                                В наше время таких инструментов не было. Товарищей с хорошим опытом разработки С++ тоже. На кувыркался тогда, дай боже. Казалось борешься с ветрянными мельницами. В последствии ушёл с С++ на более высокоуровневые языки.
                                • НЛО прилетело и опубликовало эту надпись здесь

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

                                Самое читаемое