...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdexcept> int fact(int i) noexcept(false) { if (i < 0) { // Negative factorials are undefined. throw std::domain_error("i must be >= 0"); } static const int cache[] = { fact(0), fact(1), fact(2), fact(3), fact(4), fact(5), fact(6), fact(7), fact(8), fact(9), fact(10), fact(11), fact(12), fact(13), fact(14), fact(15), fact(16) }; if (i < (sizeof(cache) / sizeof(int))) { return cache[i]; } return i > 0 ? i * fact(i - 1) : 1; } |
Implementation Details (MSVC)
In Microsoft Visual Studio 2013, the cache
array is zero-initialized as though the static initialization did not occur.
Implementation Details (GCC)
In GCC 4.8.1, upon reaching the initialization of cache
for the second time, the program will terminate with the following message:
Code Block |
---|
terminate called after throwing an instance of '__gnu_cxx::recursive_init_error' what(): std::exception |
Compliant Solution
This compliant solution avoids initializing the static local array cache
and instead relies on zero-initialization to determine whether each member of the array has been assigned a value yet and, if not, recursively compute its value. It then returns the cached value when possible or computes the value as needed.
...