Страницы

Поиск по вопросам

воскресенье, 12 января 2020 г.

Раздельная компиляция и рефакторинг

#cpp #компиляция #cpp11 #рефакторинг


Например, у меня есть несколько файлов (все по правилу odr).

SuperClass.h SuperClass.сpp

SubClass.h SubClass.cpp (наследуется от SuperClass)

main.cpp

Скомпилировал, получил SuperClass.o, SubClass.o, main.o и все объединил компоновщиком
в programm - все хорошо работает.

Потом решил переделать приватную реализацию SuperClass, добавить некоторые публичные
методы, удалить приватные поля и добавить еще один класс SuperSuperClass, от которого
теперь наследуется SuperClass. 

Скомпилировал SuperSuperClass SuperClass и объединил компоновщиком со всеми остальными
- все хорошо работает, хоть я изменил иерархию наследования, внес изменения, но не
трогал имена функций которые вызываются в остальных файлах. Но правило ODR нарушено?
Я не перекомпилировал другие файлы, в которых осталось старое определение SuperClass
и нет никакой информации об обновлении иерархии наследования.

А вдруг я захочу добавить в SuperSuperClass виртуальну функцию? При каких случаях
нужна перекомпиляция остальных файлов? 
    


Ответы

Ответ 1



На самом деле всё просто. Если вы поменяли header — все зависимые от него файлы (то есть, все cpp-файлы, которые включают его прямо или косвенно) должны быть перекомпилированы. Если вы поменяли cpp-файл, то по идее только его и надо перекомпилировать. (Если вы, разумеется, не #include-ите его в другие файлы.) Если вы пользуетесь makefile'ом, зависимости нужно прописать там, тогда повторная компиляция произойдёт автоматически, соберутся лишь нужные таргеты. Если ваш проект слишком большой для ручной расстановки зависимостей, вам поможет утилита makedepend, которая автоматизирует этот процесс.

Ответ 2



Правило ODR тут не причём вообще . То, что у Вас всё работает правильно говорит о том, что Вам Повезло. Вы имеете неопределённое поведение, но так уж случилось, что всё работает правильно. Опять повезло, но уже с компоновщиком. Компоновщик очень умён, и в o файлах, до последней сборки содержатся лишь ссылки, которые потом очень умно заменяются. Общее правило таково: если хоть что-то в заголовке было изменено(в определении класса, даже если это просто порядок функций), все эти изменения, должны быть донесены до всех объектных файлов. В противном случае UB(неопределённое поведение) Не прав я касательно ODR оказался, правило как раз в этом разделе: 3.2/6 <...>There can be more than one definition of a class type <...> Given such an entity named D defined in more than one translation unit, then each definition of D shall consist of the same sequence of tokens; and <...>

Комментариев нет:

Отправить комментарий