542 / 163 / 79
Регистрация: 23.09.2013
Сообщений: 316
|
|||||||||||
1 | |||||||||||
Перевод с С на С++19.04.2018, 17:37. Показов 3193. Ответов 3
Приветствую, имеется следующее:
1) Исходная кодовая база написанная на Си объемом примерно 150 k cloc (далее "код"). C использованием всех возможностей си - начиная от макро-магии и тайпдефов, заканчивая полиморфизмом через указателями на функции и void* в контекстах. 2) Интеграционные тесты поверх данного кода (текущие, но проходящие по логическим проверкам) 3) Библиотечные интерфейсы, в которые обернут данный код 4) Библиотеки и приложения, которые используют данные библиотечные интерфейсы на более высоком уровне. 5) Компиляторы gcc/clang с поддержкой с++17, в наличии. Целевые платформы Unix-like. Общие решаемые задачи: 1) Исправление множественных ошибок работы с памятью в сишной кодовой базе 2) Избавление от повторяющегося кода в данной кодовой базе (страницы и страницы копи-пасты с изменением пары строк на другие значения) 3) Модернизация кодовой базы (улучшение структуры, строгая типизация, упрощение интерфейсов использования). 4) На любом из этапов преобразования, база должна быть в работоспособном состоянии - нельзя взять и всё написать с нуля, или на месяц оставить код не компилирующимся. Рефакторинг выбранной части должен занимать не более 40 человеко-часов. Для решения поставленных задач был выбран "путь самурая", а именно следование правилу CPL.1 из cpp core guidelines Вопрос к аудитории: Какие изменения (путем последовательного рефакторинга исходной кодовой базы) Вы предложили бы применить к коду в первую очередь при переходе из си в c++. Для получения максимального эффекта по решаемым направлениям, при наименьших вложениях человеческих ресурсов. (Исходя из того, что данный код уже собирается как C++ код, ограничений на используемые библиотеки нет, лишь бы opensource, любые фичи из c++17 доступны). Пример структуры ожидаемого ответа: Кликните здесь для просмотра всего текста
Если, в кодовой базе есть много мест, где идет работа с массивами данных, то в первую очередь следуя совету солидного источника я бы рассмотрел возможность замены:
1) улучшит читаемость 2) расширит сферу применения данных функций 3) увеличит типобезопасность 4) позволит добавить проверки на вменяемость на момент компиляции. Но необходимо учитывать, что трудозатраты по выполнению подобной замены: высокие, поскольку изменяется количество аргументов функции, и на каждое такое изменение, придется производить обновление кода всех мест вызова. Плюсом является то, что путем рефакторинга подобную замену можно выполнять поэтапно оставляя за счет перегрузки обе версии функции до момента, когда вызовов старой версии не останется в коде. Заранее спасибо!
0
|
19.04.2018, 17:37 | |
Ответы с готовыми решениями:
3
Перевод кода с Паскаля (перевод в метры) Заменить в строке все пробелы на перевод строки, а перевод строки изменить на два перевода Разбиение строки на части, перевод строки в число и перевод числа Перевод |
Форумчанин
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
|
|
19.04.2018, 18:47 | 2 |
Пример показывает как раз то, что надо делать в последнюю очередь.
Я бы на первых этапах заменил бы всю дин. память на смарт поинтеры, вектора и прочие контейнеры. В небольшой оставшейся части мест (если такое будет), заменил бы сишную работу с памятью на плюсовую new, new[]. Потом ввёл бы сишные строки std::string/std::string_view. В принципе, надо менять именно те места, на которые есть жалобы. С самого начала нет смысла менять то, что работает и не вызывает проблем. Дальше надо начать рефакторить архитектурную часть. И сделать это сначала втупую, максимально просто, но сократив количество копипасты, а потом уже поэтапно упрощать содержимое. Важно всё делать по шагам, итерационно. Это такие вещи, в которых очень легко допустить оплошность и возможно придётся откатить большой кусок работы. Возможно дальше следовало бы ввести понятия классов и переместить часть функционала в них (по желанию). Использовать фичи ради фич я бы не стал. Если есть возможность использовать С++17, это не значит, что его надо пихать везде где надо или не надо. И не забудьте часто делать осмысленные комиты и пушить их на сервер. Одно из главных - правильно подобрать гранулярность изменений.
1
|
зомбяк
1584 / 1218 / 345
Регистрация: 14.05.2017
Сообщений: 3,939
|
|
19.04.2018, 19:16 | 3 |
Выделять копи-пасту в функцию, а затем функции группировать в цикл (меняющиеся куски строк добавлять в массив, создающийся в конструкторе или статический).
Для контроля выхода за границы использовать например std::vector::at (http://ru.cppreference.com/w/c... /vector/at) вместо operator[] массива (и, по необходимости, сделать улавливатель исключений для логов мест выхода при работе). Указатели на функции и в С++ тоже изредка могут быть полезны, особенно там, где полиморфизм получится черезмерно громоздким.
1
|
542 / 163 / 79
Регистрация: 23.09.2013
Сообщений: 316
|
|
21.04.2018, 17:20 [ТС] | 4 |
MrGluck, я привел это просто как пример, в плане формы ответа, а не как первое, что стоит сделать. Кстати, на счет замены си строк, как Вы считаете, имеет смысл двигаться по вертикальным срезам от вызывающей стороны к вызываемым функциям, или наоборот? Или выделять отдельные модули, и внутри каждого из них сначала производить замену, не трогая интерфейсы? Просто в данный момент в базе много мест, где используется strdup и char * - фактически владеющий указатель на строку, над которым рано или поздно вызывают free.
0
|
21.04.2018, 17:20 | |
21.04.2018, 17:20 | |
Помогаю со студенческими работами здесь
4
Перевод if(n*n+m*m=i) then if(i<>a[c-1]) на с++ Перевод с С++ в С# Перевод из 10-ой СС в 2-ую Перевод Перевод из 2 в 16 СС Перевод с С++ Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |