﻿# Проблемы в реальных программах \- каких только ошибок не бывает на свете\.\.\.

Тестируя работу анализатора PVS\-Studio на одном из проектов, обнаружили интересную ошибку\. Данная ошибка не имеет отношения к 64\-битной теме, хотя ее последствия диагностируются как таковые\. Но эта ошибка привлекла внимание своей необычностью, и мы решили описать ее в блоге\.

Вот код программы, который предназначался по замыслу автора для распечатки значения элементов матрицы во внутреннюю структуру\.

```cpp
Matrix3 m;
TextOutput &t = ...;
...
t.printf("%10.5f, %10.5f, %10.5f,\n%10.5f,"
  "%10.5f, %10.5f,\n%10.5f, %10.5f, %10.5f)",
  m[0, 0], m[0, 1], m[0, 2],
  m[1, 0], m[1, 1], m[1, 2],
  m[2, 0], m[2, 1], m[2, 2]);
```

Естественно, данный код некорректен, хотя и успешно компилируется\. Видимо автор в процессе разработки отвлекался работой над проектом на другом языке программирования и спутал синтаксис\. В результате, выражения вида "1, 2″ согласно правилам языка Си\+\+ имеют значение подвыражения после последней запятой\. То есть выражение "1, 2″ имеет значение 2\.

В результате, приведенный код эквивалентен следующему:

```cpp
Matrix3 m;
TextOutput& t = ...;
...
t.printf("%10.5f, %10.5f, %10.5f,\n%10.5f,"
  "%10.5f, %10.5f,\n%10.5f, %10.5f, %10.5f)",
  m[0], m[1], m[2],
  m[0], m[1], m[2],
  m[0], m[1], m[2]);
```

Класс Matrix3 имеет перегруженный оператор \[\], который возвращает указатель на тип float:

```cpp
inline const float* operator[] (int iRow) const;
```

Функции printf конечно все равно, что принимать в качестве аргументов float или float\*\. Проект собирается с уровнем предупреждений /W3 и компилятор молчит про эти подозрительные конструкции\. Чтобы получить предупреждение от Visual C\+\+ необходимо поднять уровень предупреждений до /W4\. Тогда появится диагностическое предупреждение "warning C4709: comma operator within array index expression"\.

Анализатору PVS\-Studio данный код не нравится по другой причине\. Выражение "m\[0\]" имеет тип "float \*", то есть [memsize\-тип](https://pvs-studio.ru/ru/blog/terms/0030/) и является аргументом для функции с переменным количеством аргументов\. Анализатор считает, что данный код потенциально может содержать ошибки и выдает диагностическое сообщение "error [V111](https://pvs-studio.ru/ru/docs/warnings/v111/): Call function 'printf' with variable number of arguments\. Second argument has memsize type\."