8

Value of x87 floating point control word can be checked with _control87. When a new thread starts, on my platform it seems to inherit value of floating point control word from the parent thread.

Is this undefined behavior, or am I guaranteed that if I start a new thread, and the thread library has no bugs, the control word has the same value it had in the parent thread?

In which standard is this behavior defined, and how? If it is not defined in any standard, is it defined in the processor manual, or the operating system documentation?

I am using C++ language, developing on 64-bit Windows 7, compiling for 32-bit Windows target, and executing the code with an x86-compatible processor. I need an answer specifically for this platform, but if the behavior is the same for all languages and processors, then a generic answer would be better.

VLL
  • 9,634
  • 1
  • 29
  • 54
  • 1
    C++ doesn't really define anything about the floating point environment. Even the mention of `cfenv` in the Standard is effectively non-semantic noise. – Kerrek SB Aug 29 '16 at 12:09
  • 1
    What is specific to your platform is the x87 precision bits of the control word, which bad software is notorious for changing, but which completely break the subtleties of IEEE arithmetic if they don't match the environment the compiler intended. On Windows, I think even the default is broken... – R.. GitHub STOP HELPING ICE Aug 29 '16 at 13:42
  • 1
    AFAIK, this is different for different compilers. To get the default, simply read it as the first thing you do in your application. I know from experience that, for instance, VC++ compiled DLLs even change it to their default, which can cause problems for programs that have a different default. – Rudy Velthuis Aug 29 '16 at 14:03

1 Answers1

10

The C Standard (ISO/IEC 9899:2011) has this statement in 7.6 paragraph 2:

The floating-point environment has thread storage duration. The initial state for a thread’s floating-point environment is the current state of the floating-point environment of the thread that creates it at the time of creation.

The C++ Standard (ISO/IEC 14882:2014) has this statement in 26.3.1 [cfenv.syn] paragraph 3:

The floating-point environment has thread storage duration (3.7.2). The initial state for a thread’s floatingpoint environment is the state of the floating-point environment of the thread that constructs the corresponding std::thread object (30.3.1) at the time it constructed the object.

That is, both C and C++ specify that the floating point environment is inherited from the creating thread. This floating point environment is the language level representation of any control world. Note, however, that there is no mandate that a floating point environment is supported. This hinted at, e.g., by C's footnote 12 (in 5.1.2.3; the highlighting is mine):

The IEC 60559 standard for binary floating-point arithmetic requires certain user-accessible status flags and control modes. Floating-point operations implicitly set the status flags; modes affect result values of floating-point operations. Implementations that support such floating-point state are required to regard changes to it as side effects — see annex F for details.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380