Ответ 1
Если вы используете gcc/g++, просто включите предупреждение для приведения в стиле C:
g++ -Wold-style-cast ...
Кто-нибудь знает о инструменте, который я могу использовать, чтобы найти явные приведения в стиле 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);
Если вы используете gcc/g++, просто включите предупреждение для приведения в стиле C:
g++ -Wold-style-cast ...
Тот факт, что такие отбросы настолько трудно найти, является одной из причин, по которым в первую очередь были применены приведения нового стиля. И если ваш код работает, это похоже на довольно бессмысленный бит рефакторинга - я просто изменил бы их на приведения нового стиля всякий раз, когда я модифицировал окружающий код.
Сказав это, тот факт, что у вас есть C-стиль приведения вообще в С++-коде, укажет на проблемы с кодом, который должен быть исправлен - я бы не просто сделал глобальную замену, даже если бы это было возможно.
Компилятор Offload С++ поддерживает параметры для сообщения как ошибки времени компиляции всех таких приведений и для ограничения семантики таких отбрасываний на более безопасную эквивалентность с static_cast.
Соответствующие опции:
-cp_nocstylecasts
Компилятор выдаст ошибку во всех стилях C-стиля. Стили C-стиля в С++-коде могут потенциально быть небезопасными и привести к нежелательному или undefined поведению (например, указатели на литье к несвязанным типам struct/class). Эта опция полезна для рефакторинга, чтобы найти все эти приведения и заменить их на более безопасные С++-роли, такие как static_cast.
-cp_c2staticcasts
Компилятор применяет более ограниченную семантику С++ static_cast для приведения в стиле C. Компиляция кода с включенной этой опцией гарантирует, что приведения в стиле C не менее безопасны, чем С++ static_casts
Эта опция полезна, если существующий код имеет большое количество стилей в стиле C и рефакторинг каждого актера в С++-приведениях будет слишком большим.
Поиск регулярного выражения \)\w
дает удивительно хорошие результаты.
Инструмент, который может точно анализировать исходный код С++ и выполнять автоматические пользовательские изменения (например, ваша замена заметок), это DMS Software Reengineering Toolkit.
DMS имеет полный анализатор С++, строит таблицы AST и таблиц символов и, таким образом, может перемещаться по вашему коду, чтобы надежно находить приведения стиля C. Используя шаблонные матчи и перезаписи, вы можете предоставить набор правил, которые преобразуют все такие C-образные стили в ваши желаемые эквиваленты С++.
DMS используется для выполнения массивных автоматизированных задач реинжиниринга С++ для Boeing и General Dynamics, каждая из которых включает в себя тысячи файлов.
Одна проблема с C-style casts заключается в том, что, поскольку они полагаются на скобки, которые перегружены, они не являются тривиальными. Тем не менее, регулярное выражение, такое как (например, в синтаксисе Python):
r'\(\s*\w+\s*\)'
- это начало - он совпадает с одним идентификатором в круглых скобках с необязательным пробелом внутри круглых скобок. Но, конечно, это не приведет к улавливанию, например, (void*)
casts - для получения звездочек также,
r'\(\s*\w+[\s*]*\)'
Вы также можете начать с необязательного const
для дальнейшего расширения сети и т.д. и т.д.
Когда у вас есть хороший RE, многие инструменты (от grep
до vim
, от awk
до sed
, плюс perl
, python
, ruby
и т.д.) позволяют применять его для определения всех его совпадений в вашем источнике.
Если вы используете какую-то нотацию венгерского стиля (например, iInteger
, pPointer
и т.д.), то вы можете искать, например. )p
и ) p
и т.д.
Должно быть возможно найти все эти места в разумные сроки даже для большой базы кода.
Я уже один раз ответил с описанием инструмента, который найдет и изменит все приведения, если вы захотите.
Если все, что вы хотите сделать, это найти такие отбросы, есть еще один инструмент, который сделает это легко, и на самом деле это крайнее обобщение всех предложений "регулярного выражения", сделанных здесь. Это Поисковая система исходного кода SD. Этот инструмент позволяет искать большие базы кода с точки зрения языковых элементов, составляющих каждый язык. Он предоставляет графический интерфейс, позволяющий вводить запросы, просматривать отдельные клики и показывать текст файла в точке с одним щелчком мыши. Еще один клик, и вы можете быть в своем редакторе [для многих редакторов] в файле. Инструмент также будет записывать список обращений в контекст, чтобы вы могли вернуться к ним позже.
В вашем случае следующий запрос поисковой системы, скорее всего, получит большинство отбросов:
'(' I ')' | '(' I ... '*' ')'
что означает, найти последовательность токенов, сначала быть (, второй - любым идентификатором, третье является ")" или аналогичной последовательностью, включающей что-то, что заканчивается на "*".
Вы не указываете управление пробелами, так как инструмент понимает правила пробелов языка; он даже проигнорирует комментарий в середине приведения и все еще соответствует указанному выше.
[Я - технический директор компании, которая предоставляет это.]
Я использовал это регулярное выражение в Visual Studio (2010). Поиск в окне поиска файлов: :i\):i
Спасибо за вдохновение (его сообщение)