PVS-Studio и CppCat теперь поддерживают C++/CLI
Поддержка проектов, написанных на C++/CLI не является приоритетным направлением в PVS-Studio и CppCat. Таких проектов достаточно мало, но тем не менее время от времени мы сталкиваемся с ними. Компания Microsoft на данный момент не планирует прекратить поддержку языка C++/CLI, поэтому мы решили всё-таки поддержать эту разновидность языка.Поддержка C++/CLI Wikipedia: C++/CLI — привязка языка программирования С++ к среде программирования .NET фирмы Microsoft. Она интегрирует С++ стандарта ISO с Объединённой Системой Типов (Unified Type System, UTS), рассматриваемой как часть Общей Языковой Инфраструктуры (Common Language Infrastructure, CLI). Она поддерживает и исходный уровень, и функциональную совместимость исполняемых файлов, скомпилированных с родного и управляемого C++. C++/CLI представляет собой дальнейшее развитие С++.Мы реализовали поддержку C++/CLI в PVS-Studio и CppCat на уровне, достаточном для проверки большинства проектов. Однако, у нас не было достаточного количества проектов для тестирования и какие-то конструкции языка могут обрабатываться неправильно или будут выдавать явно ложные срабатывания. Сложно уследить сразу за всем. Если при проверки ваших проектов возникнут какие-то проблемы, просим сообщить нам.
На этом статью можно закончить, но это не интересно. Поэтому мы проверили небольшой проект SlimDX о чём и расскажем ниже.
SlimDX Wikipedia: SlimDX is an open-source API to DirectX programming under .NET. SlimDX can be used from any language under the .NET runtime (due to the CLR). SlimDX can be used to develop multimedia and interactive applications (e.g. games). Enabling high performance graphical representation and enabling the programmer to make use of modern graphical hardware while working inside the .NET framework.Официальный сайт: http://slimdx.org/
Проверка была проведена с помощью анализатора кода PVS-Studio. Так как проект маленький и представляет собой обертку над другой библиотекой, то нашлось совсем немного подозрительных мест. Однако их достаточно чтобы написать о них.
Результаты проверки Ниже приведены фрагменты кода, которые показались мне неправильными.Фрагмент N1
ContainmentType BoundingBox: Contains ( BoundingBox box, BoundingSphere sphere) { … if (box.Minimum.X + radius <= sphere.Center.X && sphere.Center.X <= box.Maximum.X - radius && box.Maximum.X - box.Minimum.X > radius && <<<=== box.Minimum.Y + radius <= sphere.Center.Y && sphere.Center.Y <= box.Maximum.Y - radius && box.Maximum.Y - box.Minimum.Y > radius && box.Minimum.Z + radius <= sphere.Center.Z && sphere.Center.Z <= box.Maximum.Z - radius && box.Maximum.X - box.Minimum.X > radius) <<<=== return ContainmentType::Contains; .... } Предупреждение PVS-Studio: V501 There are identical sub-expressions 'box.Maximum.X — box.Minimum.X > radius' to the left and to the right of the '&&' operator. boundingbox.cpp 94Скорее всего этот код писался с помощью Copy-Paste и в последнюю строку забыли внести изменения. В конце выражения должно быть написано «box.Maximum.Z — box.Minimum.Z > radius».
Фрагмент N2
typedef struct DIJOYSTATE2 { … LONG rglSlider[2]; … LONG rglVSlider[2]; … LONG rglASlider[2]; … LONG rglFSlider[2]; … } DIJOYSTATE2, *LPDIJOYSTATE2;
void JoystickState: AssignState (const DIJOYSTATE2 &joystate) { … for (int i = 0; i < 2; i++ ) { sliders[i] = joystate.rglSlider[i]; asliders[i] = joystate.rglASlider[i]; vsliders[i] = joystate.rglVSlider[i]; fsliders[i] = joystate.rglVSlider[i]; } .... } Предупреждение PVS-Studio: V525 The code containing the collection of similar blocks. Check items 'rglSlider', 'rglASlider', 'rglVSlider', 'rglVSlider' in lines 93, 94, 95, 96. joystickstate.cpp 93Мне кажется этот код содержит опечатку. В последней строке скорее всего следовало использовать массив rglFSlider:
sliders[i] = joystate.rglSlider[i];
asliders[i] = joystate.rglASlider[i];
vsliders[i] = joystate.rglVSlider[i];
fsliders[i] = joystate.rglFSlider[i];
Фрагмент N3
array
Фрагмент N4
Существует класс 'TVariable', который содержит виртуальные функции:
template
CEffectVectorOwner
Аналогично:
effectload.cpp 1106 effectload.cpp 1107 Фрагмент N5 #pragma warning (disable: 4369) public enum class WaveFormatTag: System: Int32 { Pcm = WAVE_FORMAT_PCM, AdPcm = WAVE_FORMAT_ADPCM, IeeeFloat = WAVE_FORMAT_IEEE_FLOAT, MpegLayer3 = WAVE_FORMAT_MPEGLAYER3, DolbyAC3Spdif = WAVE_FORMAT_DOLBY_AC3_SPDIF, WMAudio2 = WAVE_FORMAT_WMAUDIO2, WMAudio3 = WAVE_FORMAT_WMAUDIO3, WmaSpdif = WAVE_FORMAT_WMASPDIF, Extensible = WAVE_FORMAT_EXTENSIBLE, }; #pragma warning (default: 4369) Предупреждение PVS-Studio: V665 Possibly, the usage of '#pragma warning (default: X)' is incorrect in this context. The '#pragma warning (push/pop)' should be used instead. Check lines: 1089, 1102. enums.h 1102Неправильно подавляются предупреждения компилятора. В конце восстанавливается значение по умолчанию. Более правильно в начале сохранить состояние настроек, а потом восстановить. Это нельзя назвать серьёзной ошибкой. Однако, для библиотек важно не портить настройки уровней предупреждений в проектах пользователей. О том, как правильно подойти к подавлению предупреждений описано в описании предупреждения V665.
Есть ещё несколько аналогичных недочётов в заголовочном файле «enums.h». Номера строк: 224, 267, 346.
Заключение Признаю, что первая статья про проверку C++/CLI проекта получилась скучной и краткой. Первый блин комом. Надеюсь в дальнейшем удастся проверить какой-то более крупный и интересный проект.Предлагаю скачать и проверить ваши C++/CLI проекты с помощью PVS-Studio. Мы будем рады получить ваши отзывы и комментарии.
Эта статья на английском Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Andrey Karpov. C++/CLI Now Supported in PVS-Studio and CppCat.