Using invariants

You should be careful to document how a function uses data external to the function. If the intention of the function is to change external data, you should document what the function will do. If you don't explicitly document what the function does to external data, then you must ensure that when the function finishes such data is left untouched. The reason is that the calling code will only assume what you have said in the documentation and the side-effects of changing global data may cause problems. Sometimes it is necessary to store the state of global data and return the item back to that state before the function returns.

An example of this, is the cout object. The cout object is global to your application, and it can be changed through manipulators to make it interpret numeric values in certain ways. If you change it in a function (say, by inserting the hex manipulator), then this change will remain when the cout object is used outside the function.

Create a function called read16 that reads 16 bytes from a file and prints the values out to the console both in hexadecimal form and interpreted as an ASCII character:

    int read16(ifstream& stm) 
{
if (stm.eof()) return -1;

int flags = cout.flags();
cout << hex;
string line;

// code that changes the line variable

cout.setf(flags);
return line.length();
}

This code stores the state of the cout object in a temporary variable, flags. The read16 function can change the cout object in any way necessary, but because we have the stored state it means that the object can be restored to its original state before returning.