Pull to refresh
612
17
Андрей Карпов @Andrey2008

Директор по развитию бизнеса

Send message
Поднастроил уровень предупреждений в gcc и нашел в qutIM'е пару тройку старых добрых багов с отсутствием виртуального деструктора и отсутствия явного вызова parent конструктора у тех классов, где он должен быть вызван (в данном случае QSharedData). Странно, что PVS такую ерунду не заметил.

Мы не идем по пути дублирования предупреждений, которые может выдать и компилятор. Усилий много, а пользы почти никакой. Раз хочется попробовать статический анализ, то для начала можно повысить уровень предупреждений в компиляторе. :)
Мы (пока) не пытаемся искать ошибки утечки памяти. Это дело очень сложное и требует отдельного большого исследования и работы. Не все сразу.

У статического анализа вообще очень плохо с утечками. Как и с переполнением буфера. Обычно находятся только простые случаи. Что находят лики заявляют в целях рекламы. Находить то конечно находят, но другой вопрос какой процент. ;)

Касательно QT. Если мы будем пытаться что-то искать, то естественно придется учитывать особенности наиболее популярных библиотек STL, QT, BOOST,…
Пример ложного срабатывания в Fennec:

case get_window_playlist:
	*((HWND*)rdata) = window_ml;
	return 1;

case get_window_vis:
	*((HWND*)rdata) = window_vis;
	return 1;

case get_window_eq:
	*((HWND*)rdata) = window_eq;
	return 1;

case get_window_ml:
	*((HWND*)rdata) = window_ml;
	return 1;


Сообщение:

V525 The code containing the collection of similar blocks. Check items 'window_ml', 'window_vis', 'window_eq', 'window_ml' in lines 744, 748, 752, 756. skin.c 744

В общем не понравилось, что два раза используем переменную window_ml. Но так и должно быть.

Это «средний» пример. Бывает глупее. :)
Отмечу, что анализ выполняется параллельно. Чем больше ядер, тем лучше.
Специальные замеры скорости я не делал. У нас есть база проектов для регрессионных тестов. Всего 64 проекта. Суммарное количество строк кода где-то около 7 миллионов.
На 4-х ядерной машине (Intel Core 2 Quad Q9400, 2.66 GHz) с 8 гигабайтами памяти и обыкновенным жестким диском WD3200 все эти проекты проверяются в среднем за 3 часа 50 минут.
В gcc есть. В Visual Studio .../2005/2008/2010 нет. Есть только в редакциях типа Premium (подсистема Code Analysis for C/C++). Вот и вопрос — сделать в PVS-Studio или нет?
Верю, что где то есть особенные компиляторы и архитектуры, где nullptr это не 0. Но что-то это экзотичное. В любом коде огромное количество конструкций вида:

if (ptr)
  ptr->Foo();


И как следствие никак нельзя предупреждать про это. Реализация предлагаемой диагностики разумна только в тех самым экзотических компиляторах.
Как просто и красиво!
Не понял проблемы. Код, как код. :) Прошу пояснить мысль.
Пока никак. Но хочется.
Это все только со стороны так просто кажется. Меня прям передергивает, когда кто-то что-то собирается в Си++ регулярными выражениями ловить. Бросьте эти глупости. :)

Конечно строится дерево. И много еще чего делается. Беда с препроцессором. Сейчас мы используем препроцессор от Visual C++. Соответственно туда внутрь не влезешь. Путь использовать препроцессор из boost тоже не прост.

1) Он глючит при работе с заголовочными файлами от Visual Studio. По крайней мере автор никак не исправит одну важную критичную для нас ошибку. Занят оплачиваемой работой. Почему сами не поправим — см. пункт 2.

2) Что-то поправить и расширить в реализации препроцессора от boost для сбора информации — задача для титанов. Кто хочет — можете посмотреть исходные коды. :)

Думаю кое что вполне реализуемо. Большое спасибо за эту ссылку!
Тут сложность в том, что анализ нужен на этапе препроцессирования. А это не просто. Мало того, что нужно влезть внутрь препроцессора, так и еще на том уровне уже понимать, что if это if.
Классика жанра. Мы в PVS-Studio уже умеем искать подобное. Например, только что рассматривал найденную им ошибку в Fennec Player:
for(i=0; i<16; i++); 
  for(j=0; j<32; j++) 
  { 
    settings.conversion.equalizer_bands.boost[i][j] = 0.0; 
    settings.conversion.equalizer_bands.preamp[i]   = 0.0; 
  }
Как-то в стиле К.О. :)
А те кто колбасу делает, тот её часто есть избегает. Таких примеров можно массу найти. :)
Еще было бы классно чтобы компилятор мог анализировать printf — хватает или нет переменных, все ли они того самого типа и неявных преобразований не происходит и пр.

Хочу консультация. Я вот не знаю, делать анализ строки формата и аргументов для функций типа printf или нет. Причины раздумий и нерешительности:
1) А так ли уже в современных программах нужны функции printf? Что-то тестовое распечатать, программу для курсовой написать — да, нужны. А в настоящем проекте ведь все равно все запрятано в ресурсы, выводится через нормальный boost::format и так далее. Или я не прав?
2) Это умеет делать gcc и многие другие компиляторы. Есть подозрение, что это может появиться и в Visual C++. Правда не аргумент. Ибо включая VS 2010 этой диагностики нет.
3) Основная причина. Эти диагностики есть в Code Analysis for C/C++ входящий в состав Visual Studio 2010 Premium/Ultimate.

Вопрос. Делать или нет? Есть желающие получить такие проверки для printf, sprintf и т.д.?
Красиво. Жаль, но видимо здесь статический анализ бессилен. Слишком сложно.
Как исправить понятно. Не понятно, как диагностировать. Предлагать во всех случаях объединять многострочный макрос в блок не пойдет. Будет слишком много глупых и ложных срабатываний. Люди иногда большие фрагменты программы на макросах пишут… Там такое…
Спасибо!
Пример 1. Visual C++ тоже недоволен.
Пример 2. Интересная беда, но как подступиться к диагностике (пока) не знаю.
Пример 3. Проблема с алиасингом тоже интересна. Сложно. Записал «на подумать».
Пример 4. Пример весьма специфичен на мой взгляд, в том смысле не понятно, можно ли диагностировать его автоматически. Возможно так было задумано специально…

Information

Rating
435-th
Works in
Date of birth
Registered
Activity

Specialization

Specialist
C++
C
Software development