Будет ли добавление определения enum внутри класса нарушать его двоичную обратную совместимость? - PullRequest
9 голосов
/ 18 ноября 2011

Я знаю, что добавление static функции-члена в порядке, но как насчет определения enum? Нет новых членов данных, просто это определение.


Немного фона:

Мне нужно добавить функцию-член static (в классе), которая распознает (функцию) версию адреса IP по ее строковому представлению. Первое, что приходит мне в голову, это объявить enum для IPv4, IPv6 и Unknown и сделать этот enum код возврата моей функции.

Но я не хочу нарушать двоичную обратную совместимость.

И действительно плохой вопрос (для SO) - есть ли здесь какой-либо источник или вопрос, я могу прочитать об этом подробнее? Я имею в виду - что нарушает бинарную совместимость, а что - нет. Или это зависит от многих вещей (таких как архитектура, ОС, компилятор ...)?


EDIT : Относительно комментария @PeteKirkham: Хорошо, по крайней мере, есть ли способ проверить / проверить на наличие изменений ABI или лучше опубликовать новый вопрос о что?

EDIT2 : Я только что нашел SO Вопрос: Инструмент статического анализа для обнаружения разрывов ABI в C ++ . Я думаю, что это как-то связано здесь и отвечает на часть об инструменте для проверки бинарной совместимости. Вот почему я связываю это здесь.

Ответы [ 2 ]

6 голосов
/ 18 ноября 2011

Реальный вопрос здесь, очевидно, ПОЧЕМУ сделать его классовым (статическим) членом?

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

Хотя это потенциально может нарушить ABI, для этого потребуется забавный компилятор.

Что касается поломки ABI:

  • изменение размера класса: добавление элементов данных, если только вам не удастся сохранить их в ранее неиспользованном заполнении (конечно, в зависимости от компилятора)
  • изменение выравнивания класса: изменяя элементы данных, есть хитрости для искусственного раздувания выравнивания (объединения), но для его удаления требуются прагмы или атрибуты, специфичные для компилятора, и совместимое оборудование
  • изменение макета виртуальной таблицы: добавление виртуального метода может изменить смещения предыдущих виртуальных методов в виртуальной таблице. Для gcc vtable размещается в порядке объявления, поэтому добавление виртуального метода в конце работает ... однако он не работает в базовых классах, так как макет vtable может использоваться совместно с производными классами. Лучше всего считается замороженным
  • изменение сигнатуры функции: имя символа обычно зависит как от имени самой функции, так и от типов ее аргументов (плюс для методов имя класса и квалификаторы метода). Вы можете добавить к аргументу верхний уровень const, он все равно игнорируется, и вы обычно можете изменить тип возвращаемого значения (хотя это может повлечь за собой другие проблемы). Обратите внимание, что добавление параметра со значением по умолчанию делает нарушением ABI, значения по умолчанию игнорируются применительно к сигнатурам. Лучше всего считается замороженным
  • удаление любой функции или класса, который ранее экспортировал символы (т. Е. Классы с прямыми или унаследованными виртуальными методами)

Возможно, я забыл одно или два очка, но это должно заставить вас работать уже некоторое время.

Пример того, что такое ABI: Itanium ABI .

5 голосов
/ 18 ноября 2011

Формально ... Если вы связываете файлы, которые были скомпилированы для двух разных версии вашего класса, вы нарушили одно правило определения, которое является неопределенным поведением. Практически ... о единственных вещах, которые ломаются двоичная совместимость - добавление элементов данных или виртуальных функций (не виртуальные функции в порядке), или изменение имени или подписи функция, или что-нибудь с участием базовых классов. И это, кажется, универсальный - я не знаю компилятора, где правила разные.

...