On Thu, Feb 23, 2012 at 10:12 AM, Bruno Haible <br...@clisp.org> wrote: > Michael Goffioul wrote: >> I encountered a compilation error with MSVC when compiling floor.c in >> strict floating-point mode (-fp:strict). The error is: >> >> "error C2099: initializer is not a constant" >> >> The error is triggered by the initializer for the constant variable >> TWO_MANT_DIG and is documented here: >> >> http://msdn.microsoft.com/en-us/library/t801az8a(v=vs.80).aspx > > Does adding the line > #pragma fenv_access (off) > before the initialization help? > > *** lib/floor.c.orig Thu Feb 23 11:11:48 2012 > --- lib/floor.c Thu Feb 23 11:11:43 2012 > *************** > *** 42,47 **** > --- 42,51 ---- > # define L_(literal) literal##f > #endif > > + #ifdef _MSC_VER > + # pragma fenv_access (off) > + #endif > + > /* 2^(MANT_DIG-1). */ > static const DOUBLE TWO_MANT_DIG = > /* Assume MANT_DIG <= 5 * 31. >
To illustrate the issue, I've built a little test program: #include <float.h> # define DOUBLE double # define MANT_DIG DBL_MANT_DIG #ifdef _MSC_VER # pragma fenv_access (off) #endif static const DOUBLE TWO_MANT_DIG = /* Assume MANT_DIG <= 5 * 31. Use the identity n = floor(n/5) + floor((n+1)/5) + ... + floor((n+4)/5). */ (DOUBLE) (1U << ((MANT_DIG - 1) / 5)) * (DOUBLE) (1U << ((MANT_DIG - 1 + 1) / 5)) * (DOUBLE) (1U << ((MANT_DIG - 1 + 2) / 5)) * (DOUBLE) (1U << ((MANT_DIG - 1 + 3) / 5)) * (DOUBLE) (1U << ((MANT_DIG - 1 + 4) / 5)); int main(int argc, char** argv) { double x = TWO_MANT_DIG; } With the #pragma statement, the compilation error disappears, thanks. I assume this will also solve the problem when compiling octave (which is how I found out the issue initially). Note that I think the same problem will appear in round.c and trunc.c (those are also used by octave). Michael.