Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: split Im Details

...

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:

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.

...