Рефакторинг кода C ++ для использования предварительных объявлений - PullRequest
19 голосов
/ 19 февраля 2010

У меня есть большая кодовая база, которая существует уже некоторое время, и я пытаюсь немного привести ее в порядок путем рефакторинга.Одна вещь, которую я хотел бы сделать, - найти все заголовки, куда я мог бы переслать объявление членов, вместо того, чтобы включать весь заголовочный файл.

Это довольно трудоемкий процесс, и я ищу инструмент, которыйможет помочь мне выяснить, у каких заголовков есть члены, которые могут быть объявлены вперед.

Есть ли параметр компилятора, который мог бы выдавать предупреждение или предположение, что следующий код может использовать объявление вперед?Я использую следующие компиляторы icc, gcc, sun studio и HP aCC

. Существует ли отдельный инструмент, который мог бы выполнять ту же работу?

#include "Foo.h"
...//more includes

class Bar {
.......
private:
    Foo* m_foo;
};

Ответы [ 3 ]

4 голосов
/ 19 февраля 2010

Для всего, что связано с точным анализом C ++, требуется где-то целый интерфейс C ++ (иначе вы не получите ответов, или они будут ошибаться, и это плохо работает, когда у вас «большие» приложения). Здесь не так много практических ответов.

Уже упоминалось, что GCCXML является производным от GCC пакетом, поэтому он имеет необходимый внешний интерфейс C ++. Он генерирует XML, таким образом, он генерирует МНОГО выходных данных, которые вам придется прочитать обратно, чтобы сформировать «структуру данных в памяти», предложенную в другом ответе. К сожалению, GCCXML уже создает эту структуру данных в памяти, затем экспортирует ее как XML и вынуждает вас строить ее снова. Конечно, вы можете просто использовать GCC, который строит структуру данных в памяти, но тогда вам нужно взломать GCC, чтобы он был тем, что вы хотите, и он действительно, действительно хочет быть компилятором. Это означает, что у вас будет бой, чтобы подчинить его своей воле (и объясняет, почему существует GCCXML: большинство людей не хотят этого боя).

Не упоминается внешний интерфейс Edison Design Group C ++ (EDG), который напрямую встраивает его в структуру данных памяти. Это передний конец; вам придется выполнять весь анализ самостоятельно, но ваша задача может быть достаточно простой, чтобы это не было сложным.

Последнее известное мне решение: C ++ FrontEnd для DMS . DMS является основой для построения анализа программ, а его C ++ FrontEnd является полным интерфейсом для C ++ (например, выполняет все, что делают интерфейсы GCC и Edison: анализ, построение дерева, разрешение имени / типа). И вам придется кодировать свой специальный анализ так же, как и для GCCXML и EDG, просматривая структуры данных «в памяти», создаваемые DMS.

Что действительно отличается, так это то, что DMS может затем использоваться для фактического изменения вашего исходного кода путем обновления его в структурах данных памяти и регенерации компилируемого кода из этих структур памяти, включая исходные комментарии.

3 голосов
/ 20 февраля 2010

То, что вы можете сделать, это вызвать gcc с -MM.Это создаст файлы зависимостей, которые Make может прочитать.Вместо того, чтобы использовать их, вы можете проанализировать их (с помощью perl или чего-то еще), чтобы определить, какие включения необходимы, а какие можно заменить на предварительные объявления.

3 голосов
/ 19 февраля 2010

Я не уверен, что вы найдете что-то, что делает это из коробки, но один из вариантов - написать скрипт с использованием Python и пакета pygccxml , который мог бы сделать что-то из этогоанализ для вас.

Обычно вы используете pygccxml для построения графика вашего исходного кода в памяти, а затем используете его для запроса ваших классов и функций, чтобы выяснить, что они действительно должны включить в функцию.

Так, например, вы могли бы спросить каждый класс, дать мне члены, которые являются типами указателей: затем для каждого из этих типов указателей вы могли бы работать, если в интерфейсе использовался реальный экземпляр (не указатель) класса, и если нетВы можете пометить его как кандидата для форвардного объявления.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...