Managing resources
Suppose you are writing a function that opens a file, reads from it, and closes it afterward. You are developing on a procedural platform (like most operating system APIs are) offering a set of functions to perform these tasks. Note that all “operating system” functions in this example are deliberately fictional but resemble their real-world counterparts. The functions interesting to us in that API are:
// opens the file called "name", returns a pointer // to a file descriptor for that file (nullptr on failure) FILE *open_file(const char *name); // returns the number of bytes read from the file into // buf. Preconditions: file is non-null and valid, buf // points to a buffer of at least capacity bytes, and // capacity >= 0 int read_from(FILE *file, char *buf, int capacity); // closes file. Precondition: file is non-null and valid, void close_file(FILE *file);
Suppose your code needs to process the data read from the file, but that...