Here's a more in depth example of a fictitious program that uses a config file to remember some window settings. Say your V1 config file looks something like this:
[WindowDimensions] width=400 height=300 [WindowLocation] x=100 y=100 So V1 has a size and location for the window when it starts up. Here's a little pseudo code to read that and access the variables:
Dictionary loadConfig() { String configFile = readFile("config.ini") Dictionary config = parseIni(configFile) // parses the file into a tree of Dictionaries config = fillMissingDefaults(config) // check for missing elements // and fill any with (V1) defaults Log("Window width: %d, height: %d", config["WindowDimensions"]["width"], config["WindowDimensions"]["height"]) // logs "Window width: 400, height: 300" Log("Window location: (%d, %d)", config["WindowLocation"]["x"], config["WindowLocation"]["y"]) // logs "Window location: (100, 100)" return config } Then, fully 3D holographic displays come out, and everyone buys one. V2 is written to support them. Unfortunately, the tech is still new, and windows are always full screen, though the resolution is adjustable. So the V2 config file would look something like this:
[WindowDimensions] width=400 height=300 depth=200 [WindowLocation] x=100 y=100 We've added a depth to the WindowDimensions to account for the third dimension. Note that the WindowLocation section is still there. V2 doesn't need it (everything is fullscreen), but, since we want to maintain backwards compatibility with V1, it remains there. Now, for V2's config loader:
Dictionary loadConfig() { String configFile = readFile("config.ini") Dictionary config = parseIni(configFile) // identical to parseIni() in V1 config = fillMissingDefaults(config) // check for missing elements // and fill any with (V2) defaults Log("Window width: %d, height: %d, depth: %d", config["WindowDimensions"]["width"], config["WindowDimensions"]["height"], config["WindowDimensions"]["depth"]) // logs "Window width: 400, height: 300, depth: 200" return config } Note that the config dictionary returned by parseIni() still contains WindowLocation and all it's children, but, since V2 doesn't care about it, it simply doesn't use it. Similarly, V1 can still use this new config file, even though there is now a new element in the config["WindowDimensions"] child dictionary.
Since config contains everything from config.ini, this has the added benefit of V2 saving the WindowLocation settings despite not knowing about it, simply by writing out the whole dictionary.
Now what if the config file was newly generated by V2 and thus really does have no mention of WindowLocation? That's what the defaults are for. If V1 one reads a new config file that previously had only been written by V2, then it would use, for example a default location of (300, 300), and would save that into the config file for future V1 use, along with all the V2 stuff it "doesn't" know about.