Мы хотим найти все сравнения указателей из типа класса. Например, у нас есть класс A и производные классы от A, такие как B, C ect.
A *pa;
A *pa2;
B *pb;
Все сравнения, такие как if (pa == pa2) или if (pa! = Pb), должны быть найдены в нашем исходном коде.
Я знаю, что мы можем использовать анализатор CLang, чтобы найти эти сравнения, но наш исходный код не совместим с CLang. Мы используем visual studio 2015.
Пожалуйста, не дайте решение, как; удалите класс A из исходного кода, затем попробуйте скомпилировать его, чтобы найти все применения из класса A, где он не компилируется.
У кого-нибудь есть решение, чтобы найти его? Инструмент, такой как CppCheck (который проверяет возможные ошибки) или расширение Visual Studio?
Редактировать:
Кто-нибудь знает, как я могу найти все сравнения в моем коде с синтаксисом CppDepend / CQLinq? Это также может помочь мне. CppDepend использует CLang, но продолжает анализировать, если он имеет ошибки синтаксического анализа.
наш DMS Software Reengineering Toolkit с этими C ++ 14 интерфейс может быть использован для этого.
DMS — это механизм анализа и преобразования программ общего назначения, который можно настраивать для достижения желаемого влияния на язык программирования, предоставляемый ему в качестве подключаемого модуля. Его интерфейс C ++ 14 конфигурируемо обрабатывает чистый ANSI, синтаксис в стиле GCC / Clang или синтаксис Visual Studio. Включает в себя полный препроцессор.
Для достижения цели ОП необходимо настроить DMS на:
Каждый из вышеперечисленных шагов поддерживается напрямую механизмами / API, предоставляемыми DMS и внешним интерфейсом C ++ 14. Вероятно, для достижения эффекта требуется пара страниц пользовательского кода, добавленного в DMS.
Мое решение: (как сказал @ M.M) обернуть указатели классом обертки шаблона, который реализует перегрузки операторов, такие как -> *
(так меньше проблем с компиляцией) и удаляет операторы сравнения, такие как == !=
(так что найдите сравнения с ошибками компиляции). Замена всех указателей может быть сделано с помощью регулярного выражения. (A *
с A_Wrapper
)
Я также обнаружил, что использование указателя на карте похоже на сравнение указателей. Если вы используете указатели на карте, вы также должны удалить <
-Оператор в вашем классе оболочки.
Конечно, у меня были ошибки компиляции, но эти ошибки было нетрудно решить. И кажется, что это определенное решение.
Надеюсь, это кому-нибудь поможет.
Я предполагаю, что пропускаю вопрос. Таким образом, вы просто хотите найти все экземпляры любого указателя, указывающего на тип A, B, C и т. Д., Где указатель используется в условном выражении для сравнения …
Итак, вы знаете все имена типов. Это означает, что существует конечное число типов и конечное число сравнений, например ==! = <=> = < > Верно?
Поэтому для каждого экземпляра указателя, созданного всеми типами, создайте таблицу. Это дает вам кодированное имя каждого указателя, который вы ищете.
Фред * Майфред, * Вашфред, * thefred;
учетная запись * primaryacct, * secondacct;
… и так далее…
Ваш стол будет:
myfred
yourfred
thefred
primaryacct
secondacct
Теперь для каждого экземпляра каждого — начиная с первого «myfred», найдите myfred, затем ==, затем! = И т. Д. (Поглощая все пробелы), когда вы найдете первый (левая сторона comaprison, например,
secondacct<знак равно
затем найдите правую часть) и сравните его с каждым кодированным именем указателя в созданной вами таблице. Когда у вас есть совпадение, подобное myfred! = Primaryacct, вы делаете с ним то, что вам нравится. Скажем так, ради аргументов: вы хотите выполнить глобальный поиск и замену для данного сравнения или списка сравнений, вы можете сделать это на ходу, открыв дополнительный файл для вывода, а также прочитав и найдя каждый из них. В этом случае вы можете вывести его в свою пользу в новый файл исходного кода.
По сути, просто найдите каждое сравнение, посмотрите на каждую его сторону и посмотрите, есть ли у обеих сторон закодированное имя в вашей таблице. По сути, вы просто анализируете код, используя одну и ту же таблицу идентификаторов по обе стороны конечной комбинации строк сравнения — опять же, они: [==! = <=> = < >]
Я не знаю программного инструмента, который бы это делал, но вы могли бы просто написать это довольно быстро. Конечно, это послужило бы только одной этой цели, но сделало бы работу быстро.
Конечно, я предполагаю, что ваш исходный код находится в текстовой форме, и вы можете открыть файл (ы) и прочитать его, чтобы сделать это. Если это так, то вы можете получить желаемый результат, например, список для каждого файла и строку, где встречается вхождение для каждого выраженного сравнения.
Чтобы получить целую строку кода при чтении в —
В Си — просто используйте fgets
В C ++ — используйте getline
Затем просто проанализируйте буфер, который вы прочитали, с помощью логики, описанной выше.
————— Отредактировано ————— относительно комментариев ниже
@ YusufRamazanKaragöz — Дуб — я прошу прощения за чрезмерное обобщение. Есть ли шанс, что вы могли бы предоставить пример кода, который включает в себя несколько таких вопросов — например, что если он охватывает несколько строк? Я основывал свой мыслительный процесс на том, что вы написали: «Все сравнения, такие как if (pa == pa2) или if (pa! = Pb), должны быть найдены в нашем исходном коде», и ничего более, поэтому я не стал расширяться до возврата функций, и т.д. Что касается построения таблицы — вы знаете правильные типы? Таким образом, для каждой строки, в которой есть переменная, объявленная для этих типов, вы должны ее построить. Например, если бы я хотел таблицу каждой переменной, определенной в каждой строке кода для всех файлов программы, — я бы искал во всех строках слово char. Затем после этой строки я буду искать строки, разделенные запятыми, пока не будет запятых или точек с запятой (которые могут перейти к следующей строке, поэтому используйте fgetc вместо fgets). Некоторые из этих объявлений были бы прямыми, некоторые могли бы быть * char, некоторые char [] — и т. Д. Тогда у меня был бы список каждой переменной типа char. Я имею в виду, что если вы выполняете поиск по имени типа, о котором говорите, разве вы не видите строку, в которой он встречается, и все, что объявлено после него? Если вы можете, то вы можете построить индексную таблицу. Или есть какая-то причина, по которой я не понимаю, почему это нельзя сделать? Поиск приведенных значений создает еще один набор правил синтаксического анализа и еще больше усложняет задачу, как и сравнение шаблонов с объектами. Я до сих пор не понял твою дилемму из первоначального вопроса. Я действительно хочу помочь, но, возможно, блок кода, который охватывает каждую парадигму анализа, поможет мне определить, смогу ли я. На самом деле, если бы вы могли дать мне представление о том, почему вы вообще хотите это сделать, это помогло бы мне лучше мыслить. Хотите ли вы что-то глобально изменить? Я, конечно, отложу ваше решение и перестану пытаться, если вы считаете, что усилия напрасны. Спасибо за ваше время, однако, терпение, и я надеюсь, что вы найдете решение.