- Modern C++:Efficient and Scalable Application Development
- Richard Grimes Marius Bancila
- 400字
- 2021-06-10 18:28:07
Pre- and post-conditions
A function will typically alter some data: values passed into the function, data returned by the function, or some global data. It is important when designing a function that you determine what data will be accessed and changed and that these rules are documented.
A function will have pre-conditions, assumptions about the data that it will use. For example, if a function is passed a filename, with the intention that the function will extract some data from the file, whose responsibility is it to check that the file exists? You can make it the responsibility of the function, and so the first few lines will check that the name is a valid path to a file and call operating system functions to check that the file exists. However, if you have several functions that will perform actions on the file, you will be replicating this checking code in each function and it may be better to put that responsibility on the calling code. Clearly, such actions can be expensive, so it is important to avoid both the calling code and the function to perform the checks.
Chapter 7, Diagnostics and Debugging, will describe how to add debugging code, called asserts, that you can place in your functions to check the values of the parameters to make sure that the calling code is following the pre-condition rules you have set. Asserts are defined using conditional compilation and so will only appear in debug builds (that is, C++ code compiled with debugging information). Release builds (completed code that will be delivered to the end user) will conditionally compile asserts away; this makes the code faster, and if your testing is thorough enough, you can be assured that pre-conditions are met.
You should also document the post-conditions of your function. That is, assumptions about the data returned by the function (through the function return value, out parameters, or parameters passed by a reference). Post-conditions are the assumptions that the calling code will make. For example, you may return a signed integer where the function is meant to return a positive value, but a negative value is used to indicate an error. Often functions that return pointers will return nullptr if the function fails. In both cases, the calling code knows that it needs to check the return value and only use it if it is either positive or not nullptr.