Search code examples
cvisual-c++floating-pointinitializationcl

MSVC: why "#pragma fenv_access (on)" causes "error C2099: initializer is not a constant"?


Sample code (t50.c):

#pragma fenv_access (on)
float d = 0.0 + 0.0;
int main(void)
{
    return 0;
}

Invocation:

$ cl t50.c /fp:strict
Microsoft (R) C/C++ Optimizing Compiler Version 19.25.28611 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

t50.c
t50.c(2): error C2099: initializer is not a constant

Question: why #pragma fenv_access (on) causes error C2099: initializer is not a constant? What is the reason / motivation?

Is it because on #pragma fenv_access (on) cl is not allowed to perform constant folding?


Solution

  • From the documentation:

    The compiler disables floating-point optimizations, so your code can access the floating-point environment consistently.
    ...
    The kinds of optimizations that are subject to fenv_access are:

    • Global common subexpression elimination

    • Code motion

    • Constant folding

    Treating 1.0 + 1.0 as a constant is an example of constant folding.

    Although the language specifies that this is a constant expression, so it can be used as a static initializer, the pragma is overriding this treatment because it needs to perform the addition at runtime in case it sets floating point flags.