99% of people using SemVer actually only have two types of change:
1. "Updating will probably work, but you should test anyway in case we've introduced a regression or you depend on behaviour we've decided was a bug"
2. "Updating might not work, depending on which features you're using, but you should test anyway and you'll be forced to update eventually anyway"
Given users have to respond in the same way to both, why adopt a versioning system that claims 1.12 is greater than 1.2 ?
bool operator<=(version lhs, version rhs) {
return (lhs.Major <= rhs.Major) || (lhs.Minor <= rhs.Minor) || (lhs.Patch <= rhs.Patch);
}
looks correct for anyone who have never wrote such comparison before, but of course it's wrong. The correct one is bool operator<=(version lhs, version rhs) {
return (lhs.Major < rhs.Major)
|| ((lhs.Major == rhs.Major) && ((lhs.Minor < rhs.Minor)
|| ((lhs.Minor == rhs.Minor) && (lhs.Patch <= rhs.Patch))));
}
[0] https://devblogs.microsoft.com/oldnewthing/20040213-00/?p=40... cat >test_ver.cpp << EOF
#include <cstdio>
struct version {
int Major;
int Minor;
int Patch;
version(int major, int minor, int patch)
: Major(major)
, Minor(minor)
, Patch(patch)
{ }
};
bool operator<=(version lhs, version rhs) {
return (lhs.Major < rhs.Major)
|| ((lhs.Major == rhs.Major) && ((lhs.Minor < rhs.Minor)
|| ((lhs.Minor == rhs.Minor) && (lhs.Patch <= rhs.Patch))));
}
int main(int argc, char **argv) {
version lhs(4, 3, 7);
version rhs(3, 3, 7);
printf("lhs <= rhs? %s\n", lhs <= rhs ? "true" : "false");
}
EOF
g++ test_ver.cpp -o test_ver && ./test_ver
prints lhs <= rhs? falseIt is equivalent to the following:
lhs.Major < rhs.Major
or (lhs.Major == rhs.Major and lhs.Minor < rhs.Minor)
or (lhs.Major == rhs.Major and lhs.Minor == rhs.Minor and lhs.Patch <= rhs.Patch)
Deduplicating (lhs.Major == rhs.Major) decreased readability enough to be confusing. bool operator<=(version lhs, version rhs) {
return std::tie(lhs.Major, lhs.Minor, lhs.Patch) <= std::tie(rhs.Major, rhs.Minor, rhs.Patch);
}
Wait, there is! And Python has something like this too, even more laconic: you don't need to write "std::tie", naked parentheses are enough."This update fixes important bugs and will almost certain work if the previous version did"
edit because I feel like I have to: this describes my experience, it may not be fact, your experience may differ, etc.
- the changes had to be small (and would be by nature of so close together) - we had to be very very careful about backwards incompat changes (either to the UI or the APIs).
Of course we're on the opposite end of that today, where two major browser engines are Chrome and WebKit(Safari), with Gecko often an afterthought.