Не нарушает ли добавление конструктора перемещения бинарную совместимость?
Если я добавлю в свою конструктор перемещения (или оператор присваивания), нарушу ли я двоичную совместимость? Может ли это дополнение каким-либо образом нарушить код пользователя?
class Foo {
public:
Foo();
Foo(Foo const&);
Foo& operator=(Foo const&);
// new methods:
Foo(Foo&&);
Foo& operator=(Foo&&);
};
2 ответа
По моему мнению, до тех пор, пока вы не добавите член или виртуальную функцию, это не должно влиять на двоичную совместимость, поскольку компоновка объекта не изменяется.
Если один компонент (скажем, общая библиотека, .dll
на окнах или .so
в Linux) использует старую версию библиотеки, затем она скопирует все экземпляры объекта (даже значения r) независимо от того, был ли он создан компонентом, использующим новую библиотеку (и наоборот).
Пока семантика перемещения используется для повышения производительности и, следовательно, полученные перемещенные объекты ведут себя так же, как и скопированные объекты, проблем не должно быть. Единственным отличием будет улучшение производительности, вызванное меньшим количеством обращений к памяти [de] и копий (и т. Д.) Если операции перемещения используются для создания другой семантики (перемещенный объект отличается от скопированного объекта), тогда все ставки отключены, но я не думаю, что кто-то сделал бы это специально (кроме, возможно, для обеспечения безопасности работы).
Пока бинарное расположение объекта не меняется, я не вижу, как можно представить какую-либо поломку.
Это определенно нарушает бинарную совместимость в одном направлении: код, скомпилированный с вашей новой библиотекой, не может работать со старой, поскольку конструктор перемещения не будет найден при компоновке.
Другое направление сложнее. Как правило, это не составляет большой проблемы, но код может наблюдать, по крайней мере, наличие нового оператора присваивания с хитростями SFINAE, и в итоге вы получите программу, в которой некоторые части думают, что оператор существует, а другие нет. Это может даже привести к нарушениям ODR, если один и тот же код компилируется дважды (один и тот же экземпляр шаблона в разных единицах перевода). И эти нарушения ODR могут снова вызвать ошибки соединения.