Versioning
- C++ course
- Advanced
- Lesson 52/83
- 5 min
Learn serialization versioning and compatibility.
What is versioning?
Versioning adds a version number to serialized data to ensure future compatibility. When the data format changes, the version is checked on read and a data migration is applied if needed.
Example: you first write int version = 1; to the file, then the actual data. On read you first read the version and use if (version == 1) to read in that format. Later you can change the format and set version = 2; old files can still be read through the version == 1 branch. This gives backward compatibility.
Version check and migration
On read you first read the version number. Then you write a separate read branch for each version with if / else if. When you add a new version, you keep the old branch and add a new one.
Example: if (version == 1) { ifs.read(...); } and else if (version == 2) { ifs.read(...); /* new field */ }. Version 1 files read from the first branch, version 2 from the second. This way both old and new files work with the same program. Migration is the logic of converting old data to the new format; it happens inside these branches.
Practice Write and read a versioned binary file
Write two blocks. In the first block define int version = 1; and int value = 42;, open std::ofstream ofs("data.bin", std::ios::binary) and write both with ofs.write. In the second block define int version = 0; int value = 0;, open std::ifstream ifs("data.bin", std::ios::binary) and read both with ifs.read. With if (version == 1) print std::cout << "v1: " << value;.
Starter code
#include <iostream>
#include <fstream>
// Write version and value to binary, read back and check the version
int main() {
// Add write, read and version check
return 0;
}Sample solution
#include <iostream>
#include <fstream>
int main() {
{
int version = 1;
int value = 42;
std::ofstream ofs("data.bin", std::ios::binary);
ofs.write(reinterpret_cast<const char*>(&version), sizeof(version));
ofs.write(reinterpret_cast<const char*>(&value), sizeof(value));
}
{
int version = 0;
int value = 0;
std::ifstream ifs("data.bin", std::ios::binary);
ifs.read(reinterpret_cast<char*>(&version), sizeof(version));
ifs.read(reinterpret_cast<char*>(&value), sizeof(value));
if (version == 1) {
std::cout << "v1: " << value;
}
}
return 0;
}Expected output
v1: 42
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Match each piece to its role
| Term | Meaning |
|---|---|
int version = 1 |
Version number |
if (version == 1) |
Version check |
version = 2 |
New format |
migration |
Migrates old data |
2 Why is a version number written?
- To shrink the file
- To color the output
- To speed up compilation
- For backward compatibility Correct answer
Explanation: The version number lets new programs read old files.
3 Complete the version variable
int ____ = 1;
int version = 1;
Explanation: int version = 1; sets the version number.