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, тем не менее, это приводит к некорректной работе анализатора кода.