Семантическая версия: незначительное или значительное изменение? - PullRequest
5 голосов
/ 10 марта 2019

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

У меня есть вопрос относительно того, что считается обратно совместимым изменением, а что нет.

Представьте, что я написал библиотеку, а открытый заголовок этой библиотеки содержит typedef типа данных с именем foo.В версии 1.0.0 это typedef выглядит так:

typedef struct foo_t {
    int x;
    int y;
} foo;

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

typedef struct foo_t {
    int x;
    int y;
    int z;
} foo;

Я добавил только одно поле в структуру foo_t.Казалось бы, это обратно совместимое изменение, однако вышеприведенная структура теперь является de facto другой структурой.Я не вводил новую функцию и оставлял все остальное нетронутым, но вместо этого я изменил то, что уже было там.

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

Как будет называться эта новая версия, 1.1.0или 2.0.0?

1 Ответ

5 голосов
/ 10 марта 2019

Это будет серьезное изменение версии. Структурные макеты встроены в программы конечных пользователей. Это серьезное изменение - добавлять или удалить участников; в любом случае макет изменился.

Цитирование из Библиотеки программ Linux HOWTO - §3.6. Несовместимые библиотеки:

Когда новая версия библиотеки несовместима со старой, бинарная должна измениться. В C есть четыре основные причины, по которым библиотека перестает быть двоично-совместимой:

  1. Поведение функции изменяется так, что она больше не соответствует своей первоначальной спецификации,

  2. Изменение экспортируемых элементов данных (исключение: добавление необязательных элементов к концам структур разрешено, , если эти структуры размещены только в библиотеке ).

  3. Экспортированная функция удалена.

  4. Изменен интерфейс экспортируемой функции.

Вы говорите: «Тип данных выше обычно используется для обмена данными с функциями библиотеки, однако пользователь мог использовать его в других целях». Если бы структура использовалась только для внутреннего использования и не была представлена ​​в публичном API, все было бы в порядке. Но похоже, что пользователь может сам распределить структурную переменную, а это значит, что это серьезное изменение.

Вы можете защитить свою библиотеку от этого типа оттока, используя непрозрачные структуры . Скройте содержимое структур и попросите пользователя просто передавать указатели. Именно так работает FILE *: стандарт C не определяет макет FILE, и мы, как конечные пользователи, не знаем, что внутри него.

...