Visual c++ 什么决定x87 FPU控制字的默认设置?

Visual c++ 什么决定x87 FPU控制字的默认设置?,visual-c++,floating-point,rounding,floating-accuracy,fpu,Visual C++,Floating Point,Rounding,Floating Accuracy,Fpu,是什么决定了x87 FPU控制字的默认设置——特别是精度控制字段?编译器是否基于目标处理器进行设置?是否有编译器选项来更改它 使用微软Visual C++ 2008 Express版在英特尔核心DUO处理器上,精确控制字段的默认设置为“01B”,意思是双(53位)精度。我想知道——为什么默认值不是“11”b或扩展(64位)精度 (我知道我可以用_controlfp)来改变它。从理论上看:可能是最后一个使用它的东西,或者除此之外,英特尔决定的任何东西都是一个好的默认值 从实用的角度来看:在开始工作

是什么决定了x87 FPU控制字的默认设置——特别是精度控制字段?编译器是否基于目标处理器进行设置?是否有编译器选项来更改它

使用微软Visual C++ 2008 Express版在英特尔核心DUO处理器上,精确控制字段的默认设置为“01B”,意思是双(53位)精度。我想知道——为什么默认值不是“11”b或扩展(64位)精度


(我知道我可以用_controlfp)来改变它。

从理论上看:可能是最后一个使用它的东西,或者除此之外,英特尔决定的任何东西都是一个好的默认值


从实用的角度来看:在开始工作之前,只需将其设置为所需的精度。显式默认值通常比隐含默认值好。

当操作系统设置进程(或线程)时——比如说,当程序启动时,它负责将控制寄存器初始化为默认状态(确切的默认状态可能因平台而异)。它还负责保存和恢复上下文开关周围的状态,以便您的程序不会将状态泄漏到系统上运行的其他进程中

除此之外,编译器或语言运行库可能会在执行代码之前修改状态


所以要么:Windows的默认FP状态是53位精度,要么VS2008插入代码将处理器默认设置为53位精度。Windows默认进程状态应记录在平台的ABI文档中。

Microsoft C运行时DLL(MSVCRT.DLL)中有一个错误,它会更改FPCW,这可能会根据DLL加载的顺序更改应用程序行为

因此,如果您关心FPCW设置,最好的做法不仅是在执行之前将其更改为所需的设置(即使在函数调用边界上),而且在完成后将其更改回原来的设置。(如果您调用任何函数或库,请小心被调用方,他们可能会更改函数或库,并且不会考虑到为您重新更改函数或库!)


另请注意:FPCW的修改成本很高,但检查成本不是很高。因此,如果很有可能它已经按照您想要的方式设置好了,您可以通过在修改之前检查它来节省大量时间。

我一直在想同样的原始问题。我在Windows2000(32位)上试用过VC++6和MinGW

一个简单的三行程序将FPU控制字设置为VC++的“双精度”(0x027f)和使用MinGW(0x037f)编译时的“扩展精度”。 在同一台机器上,gcc/Linux-32具有相同的扩展精度(0x37f)。
i、 e.MinGW和gcc/Linux似乎具有相同的FPU设置。

但我在问,如果我是“第一个使用它的人”,它是如何开始设置的?为什么默认值是53位而不是64位?但你不是第一个使用它的人。可能有BIOS代码在执行。这是我试图找出的一件事——在哪里被初始化。因为他使用Visual C++,我敢打赌他在Windows上,这意味着MS而不是英特尔负责默认,因为它应该是新进程的启动配置的一部分。BIOS很早以前就在Windows进程启动时使用过。这取决于您对“第一个”的定义:@archaasw-您是否对该错误有KB或MS引用?我还没有找到任何相关的东西,想知道哪个版本有这个bug。嗯,我试图把它挖出来,但没能找到。不过,当发现该漏洞时,Web和Microsoft的知识库流程仍然是一种新的功能。FPCW仍然是体系结构中最差的线程范围控制状态之一。其中的大部分状态(特别是圆形模式)都应该按指令进行编码。