...
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:
...
2015 and GCC 6.1.0, the recursive initialization of cache
deadlocks while initializing the static variable in a thread-safe manner.
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.
...