问题
In semantic versioning the general rule is to increase the minor number only when backwards compatible functionalities are introduced, otherwise the major number must be increased instead. The same approach, but with a different arithmetic, is used by libtool.
I have a question concerning what is considered a backwards compatible change and what not.
Imagine I have written a library, and the public header of this library contains a typedef
of a data type named foo
. In version 1.0.0 this typedef
looks like this:
typedef struct foo_t {
int x;
int y;
} foo;
Then I decide to change the data type, and in the next version it will look like this:
typedef struct foo_t {
int x;
int y;
int z;
} foo;
I have only added one field to the structure foo_t
. It would seem to be a backward compatible change, however the structure above is de facto another structure now. What I have done was not introducing a new function and leave untouched all the rest, but instead I have changed something that was already there.
The data type above is normally used for exchanging data with the library's functions, however the user might have used it with other purposes. If the user had written a program using version 1.0.0 and the last change constitutes a backward compatible change, the user's program must compile also with this new version.
How will this new version be called, 1.1.0 or 2.0.0?
EDIT
You can read further developments of this discussion here.
回答1:
It would be a major version change. Struct layouts are baked into end user programs. It is a breaking change to add or remove members; either way, the layout has changed.
Quoting from the Linux Program Library HOWTO — §3.6. Incompatible Libraries:
When a new version of a library is binary-incompatible with the old one the soname needs to change. In C, there are four basic reasons that a library would cease to be binary compatible:
The behavior of a function changes so that it no longer meets its original specification,
Exported data items change (exception: adding optional items to the ends of structures is okay, as long as those structures are only allocated within the library).
An exported function is removed.
The interface of an exported function changes.
You say, "The data type above is normally used for exchanging data with the library's functions, however the user might have used it with other purposes." If the struct were used internally only and not exposed in the public API you'd be okay. But it sounds like the user could allocate a struct variable themselves, which means it's a breaking change.
You can protect your library from this type of churn by using opaque structs. Hide the contents of the structs and have the user just pass around pointers. This is exactly how FILE *
works: the C standard doesn't define the layout of FILE
and we as end users don't know what's inside of it.
来源:https://stackoverflow.com/questions/55088064/semantic-versioning-minor-or-major-change