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

#c #c 11 #binary-compatibility

#c #c 11 #двоичная совместимость

Вопрос:

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

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

От

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

Для

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

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

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

1. Мой опыт показывает, что изменение сигнатур объектов всегда нарушает двоичную совместимость. Я бы всегда предполагал, что вам требуется перестройка. Однако я не знаю, что вы пытаетесь улучшить. Я полагаю, вы не хотите, чтобы какой-либо метод копирования использовался ни при каких обстоятельствах (даже в частном порядке), так что, вероятно, это так.

2. Единственное указание на «двоичную совместимость», данное Стандартом, — это правило One Definition, которое описывает достаточные условия для того, чтобы отдельно скомпилированный код совместно использовал тип данных. Это изменение нарушает правило единого определения. Связывание вместе блоков компиляции, которые не согласны таким образом, является неопределенным поведением .

3. Однако, хотя правило одного определения описывает достаточные условия, во многих реальных реализациях необходимые условия существенно слабее. Использование любых более слабых условий, чем правило One Definition, сделает ваш код непереносимым.

4. Моя цель — улучшить ясность и читаемость исходного кода, используя функции C 11, которые добавляют выразительности моему коду, и все это без нарушения какой-либо совместимости. Хотя можно ожидать определения частного конструктора копирования, пометка «удалено» совершенно ясно указывает на то, что он не подлежит копированию.

5. @JosephLarson Это всего лишь предположение, но я бы ожидал, что изменение сигнатуры функции вызывает двоичную несовместимость, если функция где-то вызывается. Здесь, в обоих случаях, функции могут не вызываться нигде в сгенерированной сборке (в первом случае это приведет к неопределенной ссылке).

Ответ №1:

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

 MyClass b{};
 

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

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

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

1. Переход на C 20 в любом случае имеет высокие шансы нарушить двоичную совместимость, поэтому я думаю, что это не проблема

2. @A.Gille Достаточно справедливо. Я просто указываю на одно потенциально критическое изменение, если вы сделаете переход. Вполне могут быть и другие, и некоторые из них повлияют на вас до обновления до C 20.

3. Поскольку в OP говорится, что ранее функций не declared but not defined было, то любые ошибки перейдут с этапа компоновки на этап компиляции. Что может помочь в больших проектах.

4. @A.Gille Я немного отредактировал вопрос. Редактирование в порядке? тогда, значит, это на самом деле не отвечает на ваш вопрос?