Может ли переход от частного конструктора/оператора присваивания к удаленному нарушить двоичную совместимость?

Использование С++11.

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

От

class MyClass {
public:
  // code
private:
  MyClass(const MyClass&);
  MyClass& operator=(const MyClass&);
  // members
};

Кому

class MyClass {
public:
  // code
  MyClass(const MyClass&) = delete;
  MyClass& operator=(const MyClass&) = delete;
private:
  // members
};

Зная, что оба объявлены, но не определены, не нарушит ли это изменение двоичную совместимость? Это что-то улучшает?


person A. Gille    schedule 02.12.2020    source источник
comment
Мой опыт показывает, что изменение сигнатур объектов всегда нарушает двоичную совместимость. Я всегда предполагал, что вам требуется восстановление. Я не знаю, что вы пытаетесь улучшить, хотя. Я предполагаю, что вы не хотите, чтобы какой-либо метод копирования использовался ни при каких обстоятельствах (даже в частном порядке), так что, вероятно, это так.   -  person Joseph Larson    schedule 02.12.2020
comment
Единственный намек на бинарную совместимость, указанный в Стандарте, — это Правило одного определения, которое описывает достаточные условия для того, чтобы отдельно скомпилированный код мог совместно использовать тип данных. Это изменение нарушает правило одного определения. Связывание блоков компиляции, которые не совпадают таким образом, является неопределенным поведением.   -  person Ben Voigt    schedule 02.12.2020
comment
Однако, хотя правило одного определения описывает достаточные условия, во многих реальных реализациях необходимые условия существенно слабее. Использование любых более слабых условий, чем правило одного определения, сделает ваш код непереносимым.   -  person Ben Voigt    schedule 02.12.2020
comment
Моя цель — улучшить ясность и читабельность исходного кода, используя функции C++11, которые добавляют выразительности моему коду, и все это без какого-либо нарушения совместимости. Хотя можно ожидать определения конструктора приватной копии, пометка его как удаленного кристально ясно указывает на то, что он не может быть скопирован.   -  person A. Gille    schedule 02.12.2020
comment
@JosephLarson Это всего лишь предположение, но я ожидаю, что изменение сигнатуры функции вызовет двоичную несовместимость, если функция где-то вызывается. Здесь в обоих случаях функции нельзя вызывать нигде в сгенерированной сборке (в первом случае это вызовет неопределенную ссылку).   -  person Daniel Langr    schedule 02.12.2020


Ответы (1)


Если вы переключитесь с первой версии на вторую, где у вас есть доступные, объявленные пользователем удаленные конструкторы, подобный код будет скомпилирован в C++11:

MyClass b{};

Но если вы обновитесь до С++ 20, этого не произойдет. Это может быть не то, что вы хотите. Если вы придерживаетесь своей первой версии, в которой конструкторы недоступны, объявление b не будет компилироваться ни в одной языковой версии, так что, по крайней мере, у вас не будет этой проблемы.

Вот демонстрация.

person cigien    schedule 02.12.2020
comment
Переход на С++ 20 в любом случае имеет высокие шансы нарушить бинарную совместимость, поэтому я думаю, что это не проблема. - person A. Gille; 02.12.2020
comment
@A.Gille Достаточно честно. Я просто указываю на одно потенциально опасное изменение, если вы совершите переход. Вполне могут быть и другие, и некоторые из них повлияют на вас до перехода на C++20. - person cigien; 02.12.2020
comment
Поскольку ОП говорит, что ранее функции не были declared but not defined, тогда любые ошибки перейдут из фазы ссылки в фазу компиляции. Что может помочь в крупных проектах. - person Martin York; 02.12.2020
comment
@A.Gille Я немного отредактировал вопрос. Редактировать нормально? тогда это не ответ на ваш вопрос? - person cigien; 02.12.2020
comment
@cigien Да, все в порядке, спасибо - person A. Gille; 02.12.2020