如果缺少编译指示STDC FENV_ACCESS,是否表示默认的舍入模式? [英] If pragma STDC FENV_ACCESS is absent, does it mean default rounding mode?

查看:73
本文介绍了如果缺少编译指示STDC FENV_ACCESS,是否表示默认的舍入模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对C标准的解释有疑问,C标准的最新草案摘自 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2454.pdf .

I have problem with interpretation of C standard, the latest draft taken from http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2454.pdf.

标准评估

该标准定义了 pragma STD FENV_ACCESS 和状态(7.6.1p2):

The standard defines pragma STD FENV_ACCESS and states (7.6.1p2):

The FENV_ACCESS pragma provides a means to inform the implementation when a program might
access the floating-point environment to test floating-point status flags or run under non-default
floating-point control modes.

目前尚不清楚为什么必须在非默认浮点控制模式下运行此编译指示.是因为

It is not clear why this pragma in necessary to run under non-default floating-point control modes. Is it because

  • 设置这些非默认模式需要写入控制模式寄存器,或者
  • 即使已经设置了非默认当前模式,总是需要编译指示吗?

在本标准的这一段之后,我们发现:

Later in this paragraph of the standard we find:

If part of a program tests floating-point status flags or establishes non-default floating-point
mode settings using any means other than the FENV_ROUND pragmas, but was translated with the
state for the FENV_ACCESS pragma "off", the behavior is undefined.

看起来像在不更改的情况下测试当前模式并非未定义的行为.但是同一段中的脚注指出:

It looks like testing current mode without changing it is not an undefined behavior. But the footnote in the same paragraph states:

In general, if the state of FENV_ACCESS is "off", the translator can assume that the flags are
not tested, and that default modes are in effect, except where specified otherwise by an
FENV_ROUND pragma.

问题

因此,如果未指定编译指示FENV_ACCESS,是否表示默认的舍入模式有效?

So if no pragma FENV_ACCESS was specified, does it mean default rounding mode is in effect?

假设不存在编译指示FENV_ROUND,并且编译器假定FENV_ACCESS默认情况下处于关闭状态,这是向后兼容的必要条件.

Let's suppose that pragma FENV_ROUND is absent as well, and compiler assumes FENV_ACCESS is off by default, it is necessary for backward compatibility.

示例

请考虑以下源代码:

#include <math.h>
float func_01(float x) {
    return nearbyint(x);
}

函数 nearbyint 被描述为(7.12.9.3)使用当前舍入模式进行舍入.但是该代码没有 pragma FENV_ACCESS .这是否意味着可能会忽略当前的舍入模式,并且 nearbyint roundeven 相同?

The function nearbyint is described (7.12.9.3) as making rounding using current rounding mode. But the code does not have pragma FENV_ACCESS. Does it mean that current rounding mode may be ignored and nearbyint is same as roundeven?

推荐答案

C草案n2454

我根据当前的C标准(2018)编写了此答案,但问题询问即将发布的标准的草案.在审核草案后,有重大更改,并且此答案不适用.

C Draft n2454

I wrote this answer based on the current C standard, 2018, but the question asks about a draft for a forthcoming standard. Upon reviewing the draft, there are significant changes, and this answer is not applicable.

值得注意的是,n2454草案在7.6.1 2中规定:

Notably, draft n2454 states in 7.6.1 2:

…如果程序的一部分使用 FENV_ROUND 编译指示以外的任何方式测试浮点状态标志或建立非默认浮点模式设置,但已转换为 FENV_ACCESS 编译指示为"off",行为未定义…

… If part of a program tests floating-point status flags or establishes non-default floating-point mode settings using any means other than the FENV_ROUND pragmas, but was translated with the state for the FENV_ACCESS pragma "off", the behavior is undefined…

此中明显缺少的是C 2018中的这段文本,紧接在非默认浮点模式设置"之后:

Notably missing from this is this text from C 2018 that appeared just after "non-default floating-point mode settings":

…或在非默认模式设置下运行,…

… or runs under non- default mode settings,…

C 2018文本表示,如果使用 FENV_ACCESS 打开的代码设置了非默认模式,并且将使用 FENV_ACCESS 编译的代码设置了,则行为未定义,仅仅是因为在 FENV_ACCESS 关闭的情况下编译的代码是在非默认模式下运行的.草案文本不包含此内容,这似乎意味着调用者可以更改模式并调用在 FENV_ACCESS 关闭的情况下编译的代码,并且应定义行为.这意味着关闭 FENV_ACCESS 编译的代码必须准备在任何浮点模式下运行.

The C 2018 text means that if code compiled with FENV_ACCESS on sets a non-default mode and sets code compiled with FENV_ACCESS off, then the behavior is not defined, merely because code compiled with FENV_ACCESS off is running in a non-default mode. The draft text does not contain this, which seems to imply that a caller can change the mode and call code compiled with FENV_ACCESS off, and the behavior should be defined. That means code compiled with FENV_ACCESS off must be prepared to run in any floating-point mode.

草案中的同一段也包含以下新文本:

The same paragraph in the draft also contains this new text:

(当执行从以 FENV_ACCESS "off"翻译的程序部分转移到以 FENV_ACCESS "on"翻译的部分时,浮动状态点状态标志未指定,并且浮点控制模式具有其默认设置.)

(When execution passes from a part of the program translated with FENV_ACCESS "off" to a part translated with FENV_ACCESS "on", the state of the floating-point status flags is unspecified and the floating-point control modes have their default settings.)

请考虑当使用 FENV_ACCESS 的例程A调用关闭了 FENV_ACCESS 的例程B时会发生什么.当B返回时,控制权从程序的访问关闭部分转到程序的访问打开部分.上面的句子说浮点控制模式处于默认设置.换句话说,从访问例程返回必须将浮点模式更改为默认模式.似乎很奇怪.因此,我不准备更新此答案以很好地涵盖草案.

Consider what happens when routine A with FENV_ACCESS on calls routine B with FENV_ACCESS off. When B returns, control passes from an access-off part of the program to an access-on part of the program. The sentence above says the floating-point control modes are then in their default settings. In other words, returning from an access-off routine must change the floating-point mode to the default. That seems odd. So I am not prepared to update this answer to cover the draft well.

目前尚不清楚为什么需要在非默认浮点控制模式下运行此编译指示.

It is not clear why this pragma in necessary to run under non-default floating-point control modes.

这是因为,如果不知道浮点操作是否处于默认模式下,则编译器生成的代码可能会有所不同(取决于C实现).例如,当在 FENV_ACCESS 设置为 off 的情况下编译代码时,编译器可以将对 sin 的调用编译为对以下假定的快速版本的调用:默认舍入.但是,如果将 FENV_ACCESS 设置为 on ,则会将调用编译为较慢的版本,以测试舍入模式并使用正弦函数的相应实现.

It is because it may be (depending on the C implementation) that the code the compiler generates must be different if floating-point operations are not known to be in the default mode. For example, when compiling code with FENV_ACCESS set to off, the compiler can compile a call to sin as a call to a fast version that assumes default rounding. But if FENV_ACCESS is set to on, it would compile the call to a slower version that tests the rounding mode and uses a corresponding implementation of the sine function.

由于在 on off 版本上必须生成的代码不同,因此编译器必须知道 FENV_ACCESS 是否为 off .

Because the code that must be generated is different for the on and off versions, the compiler must know whether FENV_ACCESS is on or off.

因此,如果未指定编译指示FENV_ACCESS,是否表示默认的舍入模式有效?

So if no pragma FENV_ACCESS was specified, does it mean default rounding mode is in effect?

不.如果不存在 FENV_ACCESS 编译指示,则编译器处于默认状态,可能是 on on或 off ,并且是实现定义的

No. If the FENV_ACCESS pragma is not present, the compiler is in its default state, which may be on or off, and that is implementation-defined.

如果默认值为 off ,并且没有编译指示,那么,是的,默认的舍入模式应该有效,这意味着,如果您已设计程序,正确地讲,那么任何没有 FENV_ACCESS 编译指示编译的代码都不会在非默认的舍入模式下执行.这要由程序设计者来确保.

If the default is off and there is no pragma, then, yes, the default rounding mode should be in effect, meaning that, if you have designed your program correctly, then any code compiled with no FENV_ACCESS pragma is never executed in a non-default rounding mode. That is up to the program designer(s) to ensure.

函数 nearbyint 被描述为(7.12.9.3)使用当前舍入模式进行舍入.但是该代码没有 pragma FENV_ACCESS .这是否意味着可能会忽略当前的舍入模式,并且 nearbyint roundeven 相同?

The function nearbyint is described (7.12.9.3) as making rounding using current rounding mode. But the code does not have pragma FENV_ACCESS. Does it mean that current rounding mode may be ignored and nearbyint is same as roundeven?

如果将 FENV_ACCESS 设置为 off (默认或显式)的代码调用 nearbyint ,则编译器可以采用默认的舍入模式生效,它可以调用本身假定为默认舍入模式的 nearbyint 的快速版本.

If code with FENV_ACCESS set to off (either by default or explicitly) calls nearbyint, then the compiler can assume the default rounding mode is in effect, and it can call the fast version of nearbyint that itself assumes the default rounding mode.

请注意,最接近的四舍五入关系"压倒了默认的四舍五入模式,但是除非附件F有效,否则C标准不会对此进行指定.

Note that round-to-nearest-ties-to-even is overwhelming the default rounding mode, but this is not specified by the C standard unless Annex F is in effect.

这篇关于如果缺少编译指示STDC FENV_ACCESS,是否表示默认的舍入模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆