>
>
>
V002. Some diagnostic messages may cont…


V002. Some diagnostic messages may contain incorrect line number.

Иногда анализатор кода может выдавать ошибку "Some diagnostic messages may contain incorrect line number". Это может происходить при использовании многострочных #pragma директив на всех поддерживаемых версиях Microsoft Visual Studio.

Любой анализатор кода работает только с препроцессированными файлами. То есть с теми файлами, в которых раскрыты все макросы (#define) и подставлены все включаемые файлы (#include). При этом в препроцессированном файле содержится информация о том, какие файлы куда подставились и в какие позиции. То есть в пропроцессированных файлах содержится информация о номерах строк.

Препроцессирование выполняется в любом случае. Для пользователя эта процедура выглядит прозрачно. Иногда препроцессор является частью анализатора кода, а иногда (как в случае с PVS-Studio) используется внешний препроцессор. В PVS-Studio используется препроцессор от Microsoft Visual Studio или Clang. Анализатор запускает для каждого обрабатываемого Си/Си++ файла компилятор командной строки cl.exe/clang.exe и генерирует с его помощью препроцессированный файл с расширением "i".

Рассмотрим ситуацию, при которой выдается сообщение "Some diagnostic messages may contain incorrect line number" и происходит сбой в позиционировании диагностических сообщений. Речь идет о многострочных директивах #pragma специального вида. Вот пример корректного кода:

#pragma warning(push) 
void test()
{
  int a;
  if (a == 1) // PVS-Studio сообщит об ошибке здесь
    return;
}

Если же директиву #pragma записать в две строки, то анализатор PVS-Studio может указать на ошибку в неправильном месте (будет сбой на одну строку):

#pragma \
  warning(push) 
void test()
{
  int a;      // PVS-Studio укажет на ошибку здесь,
  if (a == 1) // хотя реально ошибка должна быть здесь.
    return;  
}

Хотя в другом случае с многострочной директивой #pragma ошибки не будет:

#pragma warning \
  (push) 
void test()
{
  int a;
  if (a == 1) // PVS-Studio сообщит об ошибке в этой строке
    return;
}

Наши рекомендации - это либо не использовать многострочные директивы #pragma, либо использовать, но в том варианте, в котором они корректно обрабатываются.

Анализатор кода пытается обнаружить сбой с нумерацией строк в обрабатываемом файле. Этот механизм эвристический и не может гарантировать правильного определения позиционирования диагностических сообщений в коде программы. Но если удается понять, что конкретный файл содержит многострочные директивы #pragma и есть ошибка позиционирования, то и выдается сообщение: "Some diagnostic messages may contain incorrect line number".

Этот механизм работает следующим образом.

Анализатор открывает исходный Си/Си++ файл, и ищет самую последнюю лексему. Выбираются только лексемы не короче трех символов, чтобы игнорировать закрывающиеся скобки и так далее. Например, для следующего кода последней лексемой будет считаться оператор "return":

01 #include "stdafx.h"
02
03 int foo(int a)
04 {
05   assert(a >= 0 &&
06          a <= 1000);
07   int b = a + 1;
08   return b;
09 }

Найдя последнюю лексему, анализатор определит номер строки, в которой она находится. В данном случае, это строка номер 8. Далее анализатор ищет последнюю лексему в уже препроцессированном файле. Если последние лексемы не совпадают, то видимо в конце файла раскрылся макрос и понять, корректно ли расположены строки анализатор не может и игнорирует данную ситуацию. Но подобное происходит крайне редко и почти во всех случаях, последние лексемы в исходном и препроцессированном файле совпадают. Если это так, определяется номер строки, в которой расположена лексема в препроцессированном файле.

Итак, мы имеем номера строк, где расположена последняя лексема в исходном файле и в препроцессированном файле. Если эти номера строк не совпадают, то произошел сбой в нумерации строк. И в данном случае анализатор предупредит об этом пользователя сообщением "Some diagnostic messages may contain incorrect line number".

Следует учитывать, что если многострочная #pragma-директива будут находиться в файле ниже всех найденных опасных участков кода, то все номера строк для найденных ошибок будут корректны. И хотя анализатор выдаст сообщение "Some diagnostic messages may contain incorrect line number for file", это не помешает вам проанализировать выданные им диагностические сообщения.

Обратим внимание, что хотя это и не ошибка непосредственно анализатора кода PVS-Studio, тем не менее, это приводит к некорректной работе анализатора кода.