Surely they're mutually exclusive terms. I think GP was talking about cases where the developer releases a change thinking it's just an addition, but it actually breaks compatibility.
Of course, that boils down to saying that software updates sometimes have bugs. What that has to do with semver, I have no idea.
I think others covered the edge cases where additions literally break. The sibling that said I was likely referring to just plain bugs hits it pretty well, I think. I was not going for esoteric scenarios.
And yes, semver doesn't say anything about if a version is supported. However, it is a strong indication that it is. In a social expectations sort of way. If you don't plan on supporting old versions of what you are doing... use a new name for the new stuff. Nobody expects google guava to support apache commons, even though they are doing a lot of the same things. We do expect, however, that apache commons will make sure any bugs in old versions are dealt with.
With c/c++ additions can break binary compatibility can't they? Adding a field to a struct for instance will mean existing code that does a malloc for that struct won't allocate coorectly. I think there are a million other cases to consider too.
I think semver covers this pretty well actually. The public API is not just the function signatures, but basically anything that makes your API - whether it's code or documentation. So either:
- your structs in the library are opaque and the library handles all the memory management itself - addition of fields is backwards compatible, or
- your structs are open and your functions expect the structs from outside - addition of fields is not backwards compatible
The second one is still falls under "Major version X (X.y.z | X > 0) MUST be incremented if any backwards incompatible changes are introduced to the public API."
To make a comparison in a dynamic language: you've got public function `f(d)` where `d` is some dictionary with elements `a` and `b`. Now in the next version you start to require `c` - same signature in the code, but it's not backwards compatible. It's still a public API, even if defined by the documentation.
Sometimes it's possible to handle this case (if you've planned ahead) by including unused space within the original struct defintion that you can then repurpose later.
What about c++? Object allocation is always handled by new on the consumer side isn't it? Also in C, does the order of function declarations matter?
And no, after compilation, I don't believe the symbol order matters.
It's also an issue if very performance-sensitive routines need to read data from the object. In which case they already know exactly what's in there, so "pimpl" hiding has no benefit in the first place.
Implementations should be hidden if they are likely to change. In other words, there are are non-obvious data or method members and/or it's likely that functionality will be added in the future. These are the high-level architectural situations, not the leaf level ones where you optimize out every cyle possible.
Really? Do you ever call `malloc(4)` instead of `malloc(sizeof(int))` or `malloc(sizeof(*ptr))`?
glibc uses it extensively, but alas few other people know about it. Theoretically languages, like Rust, which compile to ELF executables could leverage the capability. But none do.
There are a series of posts from a libvirt developer which explain some of the mechanics:
https://www.berrange.com/posts/2011/01/13/versioning-in-the-libvirt-library/
I personally don't bother with semantic versioning at all. Where ABI compatibility matters, I'll commit to maintaining backward ABI compatibility in perpetuity using symbol versioning.[1] And maintaining backwards API compatibility is something I try to commit to as a matter of course; if I can't then I make sure builds will break loudly.I don't begrudge people using semantic versioning, I don't just don't think it's the best approach for most cases. It's just one of several crappy choices. But at least with C on Linux, ELF symbol versioning is a slam dunk when you're serious about the matter.
[1] I usually avoid depending on proprietary platform features. But this is the one area I'm comfortable and eager to lean on Linux.
It's hard, but certainly not hopeless.
> the lie that people will do security and other updates on older versions.
Semver does not say anything will be supported. You still have to know what's going on with your dependencies as far as big releases and patches go. It simply says that is old versions are still supported, they're updates will preserve compatibility.