What could be the correct data type for a C ++ software version?

I need to declare a "version" field, but I'm not sure which data type to use.

My "version" is something like "11.04." I consider the "double" a good candidate.

+4
source share
8 answers

double is probably a bad idea, unless you plan on using a whip style version converging on an irrational number. What happened to an int array or character string?

+4
source

Use two ints - one for the major version number and one for the minor. Alternatively, use the string :) A double sound does not look like a good candidate, because many numbers cannot be represented exactly in duplicate.

+4
source

A double would be a terrible candidate, since floating point numbers are not accurate enough.

I would suggest a class with several int members. Just overload some operators.

+3
source

I think I would use array<unsigned char, 4> or so. This allows you to use things like 11.2.1.3 if you ever need it, and still use less space than double. I have not yet seen that an individual version number component exceeds 255, so individual version number components greater than 255 are rare enough that I doubt that using char for each component will really be a limitation. The obvious exception is that if you decide to embed the daily build number in the version number.

If you really need versatility, you can do something like:

 typedef unsigned char component_t; array<component_t, 4> version; 

Here is just one catch with this: to read it you need to know what component_t . An obvious way to handle this would be to have a single-byte version number indicating which version of the version number you used, so anytime you change component_t (or the number of allowed components), you just increase that !:-)

+2
source

Use int and let 1000 match version 1.0, quite simple.

+2
source

I use semantic versioning , and so I created the following custom type:

version.hpp

 #include <string> #include <cstdlib> #include <iostream> class Version_Number{ public: //constructors Version_Number(); //<- constructs to 0.0.0 Version_Number(std::string const& version_number); //transformers void Major_Update(); void Minor_Update(); void Bug_Update(); //observers std::string str(); friend std::ostream& operator<<(std::ostream& os, const Version_Number& r); bool operator < (Version_Number const& other) const; bool operator > (Version_Number const& other) const; bool operator == (Version_Number const& other) const; bool operator != (Version_Number const& other) const; private: unsigned int a,b,c; }; 

version.cpp

 #include <string> #include <cstdlib> #include <iostream> #include "version_number.hpp" Version_Number::Version_Number(): a(0),b(0),c(0){} Version_Number::Version_Number(std::string const& folder_name){ std::string a_str,b_str,c_str; auto it = folder_name.begin(); while (*it != '.'){ a_str+=*it; ++it; } ++it; while (*it != '.'){ b_str+=*it; ++it; } ++it; while (it != folder_name.end()){ c_str+=*it; ++it; } a = std::atoi(a_str.c_str()); b = std::atoi(b_str.c_str()); c = std::atoi(c_str.c_str()); } void Version_Number::Major_Update(){ ++a; b = 0; c = 0; return; } void Version_Number::Minor_Update(){ ++b; c = 0; return; } void Version_Number::Bug_Update(){ ++c; return; } std::string Version_Number::str(){ std::string str; str+= std::to_string(a); str+='.'; str+= std::to_string(b); str+='.'; str+= std::to_string(c); return str; } bool Version_Number::operator < (Version_Number const& other) const{ if (a > other.a){return false;} if (a < other.a){return true;} if (b > other.b){return false;} if (b < other.b){return true;} if (c > other.c){return false;} if (c < other.c){return true;} return false; } bool Version_Number::operator > (Version_Number const& other) const{ if (a < other.a){return false;} if (a > other.a){return true;} if (b < other.b){return false;} if (b > other.b){return true;} if (c < other.c){return false;} if (c > other.c){return true;} return false; } bool Version_Number::operator == (Version_Number const& other) const{ if (a == other.a){ if (b == other.b){ if (c == other.c){ return true; } } } return false; } bool Version_Number::operator != (Version_Number const& other) const{ if (a == other.a){ if (b == other.b){ if (c == other.c){ return false; } } } return true; } std::ostream& operator<<(std::ostream& os, const Version_Number& r){ os << ra << '.' << rb << '.' << rc; return os; } 
+2
source

Some libraries use tricks like:

 #define PKG_MAJOR (3) // example values... #define PKG_MINOR (7) #define PKG_MICRO (11) const unsigned long pkg_version = (PKG_MAJOR * 1000 + PKG_MINOR) * 1000 + PKG_MICRO; 

ie, pkg_version - 3007011.

+1
source

how about using unsigned int or such? I just saw this in linux kernel Makefile

 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) 

You have kernel version a , major version b and minor version c . You can easily compare the order of the two versions. If you want the version to be in good print format, you can add a function to create a version string, for example. "2.6.38" . (Of course, you are limited to no more than 256 sub-versions ... use unsigned long long ?)

+1
source

Source: https://habr.com/ru/post/1384763/


All Articles