to the top
close form
Для получения триального ключа
заполните форму ниже
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Бесплатная лицензия PVS-Studio для специалистов Microsoft MVP
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Мне интересно попробовать плагин на:
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
check circle
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
>
PVS-Studio теперь поддерживает C++/CLI

PVS-Studio теперь поддерживает C++/CLI

04 Май 2014

Поддержка проектов, написанных на C++/CLI, не является приоритетным направлением в PVS-Studio. Таких проектов достаточно мало, но тем не менее время от времени мы сталкиваемся с ними. Компания Microsoft на данный момент не планирует прекратить поддержку языка C++/CLI, поэтому мы решили всё-таки поддержать эту разновидность языка.

0255_Support_CLI_ru/image1.png

Поддержка C++/CLI

Wikipedia: C++/CLI - привязка языка программирования С++ к среде программирования .NET фирмы Microsoft. Она интегрирует С++ стандарта ISO с Объединённой Системой Типов (Unified Type System, UTS), рассматриваемой как часть Общей Языковой Инфраструктуры (Common Language Infrastructure, CLI). Она поддерживает и исходный уровень, и функциональную совместимость исполняемых файлов, скомпилированных с родного и управляемого C++. C++/CLI представляет собой дальнейшее развитие С++.

Мы реализовали поддержку C++/CLI в PVS-Studio на уровне, достаточном для проверки большинства проектов. Однако, у нас не было достаточного количества проектов для тестирования и какие-то конструкции языка могут обрабатываться неправильно или будут выдавать явно ложные срабатывания. Сложно уследить сразу за всем. Если при проверки ваших проектов возникнут какие-то проблемы, просим сообщить нам.

На этом статью можно закончить, но это не интересно. Поэтому мы проверили небольшой проект 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.

Сайт: https://github.com/SlimDX/slimdx

Проверка была проведена с помощью анализатора кода 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<SoundEffectResult>^ SecondarySoundBuffer::SetEffects(
  array<Guid>^ effects )
{
  DWORD count = effects->Length;
  ....
  if( effects != nullptr && count > 0 )
  ....
}

Предупреждение PVS-Studio: V595 The 'effects' pointer was utilized before it was verified against nullptr. Check lines: 66, 73. secondarysoundbuffer.cpp 66

В начале указатель 'effects' разыменовывается. Затем ниже в коде он проверяется на равенство нулю.

Фрагмент N4

Существует класс 'TVariable', который содержит виртуальные функции:

template<typename IBaseInterface>
struct TVariable : public IBaseInterface
{
  virtual BOOL IsValid() { .... }
  ....
};

От этого класса наследуется класс SMember. Обратите внимание, что в поля этого класса записываются нули с помощью функции ZeroMemory().

struct SMember :
  public TVariable<TMember<ID3DX11EffectVariable> >
{
};

CEffectVectorOwner<SMember> m_pMemberInterfaces;
ZeroMemory
HRESULT CEffect::CopyMemberInterfaces(....)
{
  ....
  ZeroMemory( &m_pMemberInterfaces[i],
              sizeof(SMember) * ( Members - i ) );
  ....
}

Предупреждение PVS-Studio: V598 The 'memset' function is used to nullify the fields of 'SMember' class. Virtual method table will be damaged by this. effectnonruntime.cpp 1739

Так как есть виртуальные функции, то класс SMember содержит указатель на таблицу виртуальных методов. Это указатель будет испорчен при вызове функции ZeroMemory().

Аналогично:

  • 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. Мы будем рады получить ваши отзывы и комментарии.

Популярные статьи по теме
Под капотом SAST: как инструменты анализа кода ищут дефекты безопасности

Дата: 26 Янв 2023

Автор: Сергей Васильев

Сегодня речь о том, как SAST-решения ищут дефекты безопасности. Расскажу, как разные подходы к поиску потенциальных уязвимостей дополняют друг друга, зачем нужен каждый из них и как теория ложится на…
Ложные представления программистов о неопределённом поведении

Дата: 17 Янв 2023

Автор: Гость

Неопределённое поведение (UB) – непростая концепция в языках программирования и компиляторах. Я слышал много заблуждений в том, что гарантирует компилятор при наличии UB. Это печально, но неудивитель…
Топ-10 ошибок в C++ проектах за 2022 год

Дата: 29 Дек 2022

Автор: Владислав Столяров

Дело идёт к Новому году, а значит, самое время традиционно вспомнить десять самых интересных срабатываний, которые нашёл PVS-Studio в 2022 году.
PVS-Studio и RPCS3: лучшие предупреждения в один клик

Дата: 12 Дек 2022

Автор: Александр Куренев

Best Warnings — режим анализатора, оставляющий в окне вывода 10 лучших предупреждений. Мы предлагаем вам ознакомиться с обновлённым режимом Best Warnings на примере проверки проекта RPCS3.
Holy C++

Дата: 23 Ноя 2022

Автор: Гость

В этой статье постараюсь затронуть все вещи, которые можно без зазрения совести выкинуть из С++, не потеряв ничего (кроме боли), уменьшить стандарт, нагрузку на создателей компиляторов, студентов, из…

Комментарии (0)

Следующие комментарии next comments
close comment form
Unicorn with delicious cookie
Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо