Инструмент для поиска стилей в стиле C

Кто-нибудь знает о инструменте, который я могу использовать, чтобы найти явные приведения в стиле C в коде? Я рефинансирую некоторый код на С++ и хочу заменить C-style casts, где это возможно.

Примером C-стиля может быть:

Foo foo = (Foo) bar;

Напротив, примеры стилей С++ были бы следующими:

Foo foo = static_cast<Foo>(bar);
Foo foo = reinterpret_cast<Foo>(bar);
Foo foo = const_cast<Foo>(bar);

Ответ 1

Если вы используете gcc/g++, просто включите предупреждение для приведения в стиле C:

g++ -Wold-style-cast ...

Ответ 2

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

Сказав это, тот факт, что у вас есть C-стиль приведения вообще в С++-коде, укажет на проблемы с кодом, который должен быть исправлен - я бы не просто сделал глобальную замену, даже если бы это было возможно.

Ответ 3

Компилятор Offload С++ поддерживает параметры для сообщения как ошибки времени компиляции всех таких приведений и для ограничения семантики таких отбрасываний на более безопасную эквивалентность с static_cast.

Соответствующие опции:

-cp_nocstylecasts   

Компилятор выдаст ошибку во всех стилях C-стиля. Стили C-стиля в С++-коде могут потенциально быть небезопасными и привести к нежелательному или undefined поведению (например, указатели на литье к несвязанным типам struct/class). Эта опция полезна для рефакторинга, чтобы найти все эти приведения и заменить их на более безопасные С++-роли, такие как static_cast.

-cp_c2staticcasts   

Компилятор применяет более ограниченную семантику С++ static_cast для приведения в стиле C. Компиляция кода с включенной этой опцией гарантирует, что приведения в стиле C не менее безопасны, чем С++ static_casts

Эта опция полезна, если существующий код имеет большое количество стилей в стиле C и рефакторинг каждого актера в С++-приведениях будет слишком большим.

Ответ 4

Поиск регулярного выражения \)\w дает удивительно хорошие результаты.

Ответ 5

Инструмент, который может точно анализировать исходный код С++ и выполнять автоматические пользовательские изменения (например, ваша замена заметок), это DMS Software Reengineering Toolkit.

DMS имеет полный анализатор С++, строит таблицы AST и таблиц символов и, таким образом, может перемещаться по вашему коду, чтобы надежно находить приведения стиля C. Используя шаблонные матчи и перезаписи, вы можете предоставить набор правил, которые преобразуют все такие C-образные стили в ваши желаемые эквиваленты С++.

DMS используется для выполнения массивных автоматизированных задач реинжиниринга С++ для Boeing и General Dynamics, каждая из которых включает в себя тысячи файлов.

Ответ 6

Одна проблема с C-style casts заключается в том, что, поскольку они полагаются на скобки, которые перегружены, они не являются тривиальными. Тем не менее, регулярное выражение, такое как (например, в синтаксисе Python):

r'\(\s*\w+\s*\)'

- это начало - он совпадает с одним идентификатором в круглых скобках с необязательным пробелом внутри круглых скобок. Но, конечно, это не приведет к улавливанию, например, (void*) casts - для получения звездочек также,

r'\(\s*\w+[\s*]*\)'

Вы также можете начать с необязательного const для дальнейшего расширения сети и т.д. и т.д.

Когда у вас есть хороший RE, многие инструменты (от grep до vim, от awk до sed, плюс perl, python, ruby и т.д.) позволяют применять его для определения всех его совпадений в вашем источнике.

Ответ 7

Если вы используете какую-то нотацию венгерского стиля (например, iInteger, pPointer и т.д.), то вы можете искать, например. )p и ) p и т.д.

Должно быть возможно найти все эти места в разумные сроки даже для большой базы кода.

Ответ 8

Я уже один раз ответил с описанием инструмента, который найдет и изменит все приведения, если вы захотите.

Если все, что вы хотите сделать, это найти такие отбросы, есть еще один инструмент, который сделает это легко, и на самом деле это крайнее обобщение всех предложений "регулярного выражения", сделанных здесь. Это Поисковая система исходного кода SD. Этот инструмент позволяет искать большие базы кода с точки зрения языковых элементов, составляющих каждый язык. Он предоставляет графический интерфейс, позволяющий вводить запросы, просматривать отдельные клики и показывать текст файла в точке с одним щелчком мыши. Еще один клик, и вы можете быть в своем редакторе [для многих редакторов] в файле. Инструмент также будет записывать список обращений в контекст, чтобы вы могли вернуться к ним позже.

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

'(' I ')'  | '(' I ... '*' ')'

что означает, найти последовательность токенов, сначала быть (, второй - любым идентификатором, третье является ")" или аналогичной последовательностью, включающей что-то, что заканчивается на "*".

Вы не указываете управление пробелами, так как инструмент понимает правила пробелов языка; он даже проигнорирует комментарий в середине приведения и все еще соответствует указанному выше.

[Я - технический директор компании, которая предоставляет это.]

Ответ 9

Я использовал это регулярное выражение в Visual Studio (2010). Поиск в окне поиска файлов: :i\):i

Спасибо за вдохновение (его сообщение)