Go back to Richel Bilderbeek's homepage.
Go back to Richel Bilderbeek's C++ page.
Function design is the correct design of a function. Exercise #2: correct function declarations is an exercise in correct function design.
The most important to get correct is the function declaration.
Here is some advice:
General
- Avoid writing long functions [1-2,5,35]
- Avoid using functions with a large number of arguments [36]
- Prefer functions over macros [23,24]
- If a function may have to be evaluated at compile time, declare it constexpr [7]
The name of the function should say what it does
- Do use names like Swap, GetDistance, StrToInt
- Do not use names like DoIt, Transmogrify, Stuff
- Exceptions: Transmogrify is a function name commonly used in the literature to denote a function you are not aware of what it is doing
A function should perform a single logical operation [4]
- Do not use names with 'And' in it, like SwapAndGetMean
- Do use two functions instead, Swap and GetMean
- Exceptions: some mathematical functions can cooperate and so improve runtime speed: MeanAndStdDev executes faster then calling the seperate functions for Mean and StdDev
The return type is expected from the name of the function
- If a function cannot return, mark it [[noreturn]] [8]
- Do give a function a void return type when it has no return type
- Do return a non-pointer non-reference object when a function is expected to always execute successfully on the assumptions that its arguments are valid
-
Return a result as a return value rather than modifying an object through an argument [11]
-
Do return a pointer (or better: a smart pointer) to a
data type when the return type can be null, that is: empty. If the
pointer needs to be read-only, make it const (for
example 'const T * const GetT()', where GetT is a function that returns a pointer to a T)
-
Do not make a function return a reference to a function's local variable [6,31], this leads to undefined behavior
-
Do not make a function return an error code, use exceptions instead [32]
The function arguments are expected from the name of the function
-
A function declared with an empty parameter list takes no arguments [37]. Or: write 'int f()' instead of 'int f(void)' [37]
-
Prefer pass-by-reference-to-const to pass-by-value [30]
-
Use pass-by-non-const-reference only if you have to [14]
-
Do use a non-pointer reference object for expensive-to-copy data types,
like std::string, std::vector<int> or Database. Make the
argument const if it must be marked read-only [10]
-
Do use a non-pointer non-reference object for standard data types like int [9].
Make the argument const if it must be marked read-only
-
Do use a pointer (or better: a smart pointer) to a
data type when the argument can be nullptr/null/empty [13].
If the pointer needs to be read-only,
make it const (for example 'void CoutT(const T * const t)', where CoutT is a function that uses std::cout on a T)
-
Avoid passing arrays as pointers [16]
-
Assume that a char* or a const char* argument points to a C-style string [15]
-
Use rvalue references to implement move and forwarding [12]
-
Pass a homogeneous list of unknown length as an std::initializer_list or as some other container [17]
-
Avoid unspecified numbers of arguments (...) [18]
-
Prefer to pass function objects (including lambdas) and virtual functions to pointers to functions [22]
Specify preconditions and postconditions for your functions [21,25-28]
-
Do use assert and exceptions
to make clear to the client which input the function cannot handle. For example, the square root of a negative number does not exist
-
Do not use error codes as return types, use exceptions instead [32]
Exception handling
Function overloading
- Use overloading when functions perform conceptually the same task on different types [19]
- When overloading on integers, provide functions to eliminate common ambiguities [20]
- Herb Sutter, Andrei Alexandrescu. C++ coding standards: 101 rules, guidelines, and best practices. ISBN: 0-32-111358-6. Item 20: 'Avoid long functions. Avoid deep nesting'
- Joint Strike Fighter Air Vehicle C++ Coding Standards for the System Development and Demonstration Program. Document Number 2RDU00001 Rev C. December 2005. AV Rule 1: 'Any one function (or method) will contain no more than 200 logical source lines of code.'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[1] "Package meaningful operations as carefully named functions'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[2] A function should perform a single logical operation'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[3] Keep functions short'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[4] Don't return pointers or references to local variables'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[5] If a function may have to be evaluated at compile time, declare it constexpr'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[6] If a function cannot return, mark it [[noreturn]]'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[7] Use pass-by-value for small objects'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[8] Use pass-by-const-reference to pass large values that you don't need to modify'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[9] Return a result as a return value rather than modifying an object through an argument'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[10] Use rvalue references to implement move and forwarding'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[11] Pass a pointer if "no object" is a valid alternative (and represent "no object" by nullptr)'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[12] Use pass-by-non-const-reference only if you have to'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[14] Assume that a char* or a const char* argument points to a C-style string'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[15] Avoid passing arrays as pointers'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[16] Pass a homogeneous list of unknown length as an initializer_list (or as some other container)'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[17] Avoid unspecified numbers of arguments (...)'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[18] Use overloading when functions perform conceptually the same task on different types'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[19] When overloading on integers, provide functions to eliminate common ambiguities'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[20] Specify preconditions and postconditions for your functions'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[21] Prefer function objects (including lambdas) and virtual functions to pointers to functions'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 12.7. Advice. page 341: '[22] Avoid macros'
- Herb Sutter, Andrei Alexandrescu. C++ coding standards: 101 rules, guidelines, and best practices. 2005. ISBN: 0-32-111358-6. Item 16: 'Avoid macro's'.
- Herb Sutter, Andrei Alexandrescu. C++ coding standards: 101 rules, guidelines, and best practices. ISBN: 0-32-111358-6. Chapter 68: 'Assert liberally to document internal assumptions and invariants'
- Bjarne Stroustrup. The C++ Programming Language (3rd edition). 1997. ISBN: 0-201-88954-4. Advice 24.5.18: 'Explicitly express preconditions, postconditions, and other assertions as assertions'
- Steve McConnell. Code Complete (2nd edition). 2004. ISBN: -735619670. Chapter 8.2 'Assertions', paragraph 'Guidelines for using asserts': 'Use assertions to document and verify preconditions and postconditions'
- Steve McConnell. Code Complete (2nd edition). 2004. ISBN: -735619670. Chapter 8.2 'Assertions', paragraph 'Guidelines for using asserts': 'Use assertions for conditions that should never occur'.
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 13.7. Advice. page 387: '[8] 'Don't try to catch every exception in every function'
- Scott Meyers. Effective C++ (3rd edition). ISBN: 0-321-33487-6. Item 20: Prefer pass-by-reference-to-const to pass-by-value.
- Scott Meyers. Effective C++ (3rd edition). ISBN: 0-321-33487-6. Item 21: Don't try to return a reference when you must return an object.
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 13.7. Advice. page 386: '[3] Use exceptions for error handling'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 13.7. Advice. page 387: '[33] Assume that every exception that can be thrown by a function will be thrown'
- Bjarne Stroustrup. The C++ Programming Language (4th edition). 2013. ISBN: 978-0-321-56384-2. Chapter 13.7. Advice, page 387: '[23] If your function may not throw, declare it noexcept'
- Bruce Eckel. Thinking in C++, second edition, volume 1. 2000. ISBN: 0-13-979809-9. Chapter B: Programming Guidelines. Item 15: 'Watch for long member function definitions. A function that is long and complicated is difficult and expensive to maintain, and is probably trying to do too much all by itself. If you see such a function, it indicates that, at the least, it should be broken up into multiple functions. It may also suggest the creation of a new class.'
- Bruce Eckel. Thinking in C++, second edition, volume 1. 2000. ISBN: 0-13-979809-9. Chapter B: Programming Guidelines. Item 16: 'Watch for long argument lists. Function calls then become difficult to write, read and maintain. Instead, try to move the member function to a class where it is (more) appropriate, and/or pass objects in as arguments.'
- Working Draft, Standard for Programming Language C++. 2014-08-22. N3936. Paragraph C.1.7. First change. 'In C++, a function declared with an empty parameter list takes no arguments. In C, an empty parameter list means that the number and type of the function arguments are unknown.'
Go back to Richel Bilderbeek's C++ page.
Go back to Richel Bilderbeek's homepage.
