Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Updated implementation details to modern versions of MSVC and GCC

...

Code Block
bgColor#FFCCCC
langcpp
#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.

...