如果 pragma STDC FENV_ACCESS 不存在,是否意味着默认舍入模式?

2024-04-15

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

标准评价

该标准定义了pragma STD FENV_ACCESS并指出(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.

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

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

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

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.

看起来测试当前模式而不改变它不是未定义的行为。但同一段的脚注指出:

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.

问题

因此,如果未指定 pragma FENV_ACCESS,是否意味着默认舍入模式有效?

假设 pragma FENV_ROUND 也不存在,并且编译器假定 FENV_ACCESS 默认情况下处于关闭状态,这是向后兼容所必需的。

Example

考虑以下源代码:

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

功能nearbyint被描述为(7.12.9.3)使用当前舍入模式进行舍入。但代码中没有pragma FENV_ACCESS。这是否意味着当前的舍入模式可以被忽略并且nearbyintroundeven?


C 草案 n2454

我根据当前的 C 标准 2018 写了这个答案,但问题询问的是即将推出的标准草案。经审查,草案存在重大变化,本答复不适用。

值得注意的是,草案 n2454 在 7.6.1 2 中指出:

…如果程序的一部分测试浮点状态标志或使用除FENV_ROUNDpragmas,但与状态一起翻译为FENV_ACCESSpragma“off”,行为未定义......

值得注意的是,其中缺少 C 2018 中的这段文本,该文本出现在“非默认浮点模式设置”之后:

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

C 2018 文本意味着如果代码编译为FENV_ACCESSon 设置非默认模式并设置编译的代码FENV_ACCESSoff,则行为未定义,仅仅因为代码编译为FENV_ACCESSoff 正在非默认模式下运行。草稿文本不包含此内容,这似乎暗示调用者可以更改模式并调用使用 编译的代码FENV_ACCESS关闭,并且应该定义行为。这意味着代码编译为FENV_ACCESSoff 必须准备好在任何浮点模式下运行。

草案中的同一段落还包含以下新案文:

(当执行从用翻译的程序的一部分传递时FENV_ACCESS“关闭”翻译为的部分FENV_ACCESS“on”时,浮点状态标志的状态未指定,浮点控制模式具有默认设置。)

考虑当例程 A 与FENV_ACCESS调用例程 B 时FENV_ACCESS离开。当 B 返回时,控制从程序的访问关闭部分传递到程序的访问打开部分。上面的句子表示浮点控制模式处于默认设置。换句话说,从访问关闭例程返回必须将浮点模式更改为默认值。这看起来很奇怪。所以我不准备更新这个答案来很好地涵盖草案。

2018年C题答案

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

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

因为必须生成的代码不同on and off版本,编译器必须知道是否FENV_ACCESS is on or off.

因此,如果未指定 pragma FENV_ACCESS,是否意味着默认舍入模式有效?

不可以。如果FENV_ACCESSpragma 不存在,编译器处于默认状态,这可能是on or off,这是实现定义的。

如果默认是off并且没有 pragma,那么,是的,默认的舍入模式should有效,这意味着,如果您正确设计了程序,则任何编译的代码都不会FENV_ACCESSpragma 永远不会在非默认舍入模式下执行。这由程序设计者来确保。

功能nearbyint被描述为(7.12.9.3)使用当前舍入模式进行舍入。但代码中没有pragma FENV_ACCESS。这是否意味着当前的舍入模式可以被忽略并且nearbyintroundeven?

如果代码与FENV_ACCESS set to off(默认或显式)调用nearbyint,那么编译器可以假设默认舍入模式有效,并且它可以调用快速版本nearbyint它本身采用默认的舍入模式。

请注意,round-to-nearest-ties-to-even 压倒了默认舍入模式,但除非附录 F 生效,否则 C 标准并未指定这一点。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果 pragma STDC FENV_ACCESS 不存在,是否意味着默认舍入模式? 的相关文章

  • 是否可以从 C++ 应用程序调用 C# 应用程序?

    我是一名编程学生 现在我已经上了两门 C 课程 这个学期我将参加我的第一门 C 课程 出于好奇 是否可以从 C 应用程序调用 C 应用程序 如果是的话 是否还可以检查运行该程序的计算机是否具有 NET框架 我只是很好奇 我想如果可能的话 这
  • 我如何知道 C 程序的可执行文件是在前台还是后台运行?

    在我的 C 程序中 我想知道我的可执行文件是否像这样在前台运行 a out 或者像这样 a out 如果你是前台工作 getpgrp tcgetpgrp STDOUT FILENO or STDIN FILENO or STDERR FIL
  • 锁定 ASP.NET 应用程序变量

    我在 ASP NET 应用程序中使用第三方 Web 服务 对第 3 方 Web 服务的调用必须同步 但 ASP NET 显然是多线程的 并且可能会发出多个页面请求 从而导致对第 3 方 Web 服务的同时调用 对 Web 服务的调用封装在自
  • C free() 是如何工作的? [复制]

    这个问题在这里已经有答案了 可能的重复 malloc 和 free 如何工作 https stackoverflow com questions 1119134 how malloc and free work include
  • 进程退出后 POSIX 名称信号量不会释放

    我正在尝试使用 POSIX 命名信号量进行跨进程同步 我注意到进程死亡或退出后 信号量仍然被系统打开 在进程 打开它 死亡或退出后是否有办法使其关闭 释放 早期的讨论在这里 当将信号量递减至零的进程崩溃时 如何恢复信号量 https sta
  • MFC CList 支持复制分配吗?

    我在 MSVC 中查找了 CList 定义afxtempl h http www cppdoc com example mfc classdoc MFC AFXTEMPL H html并记录在MSDN http msdn microsoft
  • 在 ASP.NET MVC 中将模型从视图传递到控制器

    我正在 ASP NET MVC 中开发我的第一个应用程序 但遇到了一个我无法解决的问题 即使在阅读了整个互联网之后也是如此 因此 我有几个使用视图模型创建的视图 它们是报告 这些视图模型是根据用户选择标准填充的 我正在尝试构建一种接受模型并
  • 将下拉列表与字典绑定

    我将字典绑定到下拉列表 举例来说 我的字典中有以下项目 Test1 123 Test2 321 我希望下拉文本采用以下格式 Test1 Count 123 Test2 Count 321 我沿着以下路径走 但没有运气 MyDropDown
  • 有什么方法可以重载 C# 中的扩展方法吗?

    我有以下模型模式 public abstract class PARENTCLASS public class CHILD A CLASS PARENTCLASS public static class EXTENSION public s
  • 如何在win32中使用GetSaveFileName保存文件?

    我编写此代码是为了获取 fileName 来保存我的文件 include stdafx h include
  • Xamarin - SignalR 挂在连接上

    我正在尝试将我的 Xamarin 应用程序连接到托管在 Azure 上的 SignalR 后端 我遇到的问题是每次我在 HubConnection 上调用 StartAsync 时 它都会挂起客户端并且请求永远不会完成 我尝试通过应用程序进
  • Resharper:IEnumerable 的可能多重枚举

    我正在使用新的 Resharper 版本 6 在我的代码中的几个地方 它给一些文本加了下划线 并警告我可能存在IEnumerable 可能的多重枚举 我理解这意味着什么 并在适当的情况下采纳了建议 但在某些情况下 我不确定这实际上是一个大问
  • 如何在 C# 中获取 Json 数组?

    我有一个像这样的 Json 字符串 我想将它加载到 C 数组中 当我尝试这样做时 我收到异常 我的字符串 customerInformation customerId 123 CustomerName Age 39 Gender Male
  • 无法在 C# 中为 EventArgs 分配使用派生类型的事件处理程序

    所以我有一个事件声明如下 public event EventHandler OnChangeDetected 然后我有以下处理程序被分配给该事件 myObject OnChangeDetected OnTableChanged 我的理解是
  • 浮点字节序?

    我正在为实时海上模拟器编写客户端和服务器 并且由于我必须通过套接字发送大量数据 因此我使用二进制数据来最大化可以发送的数据量 我已经了解整数字节顺序以及如何使用htonl and ntohl为了规避字节顺序问题 但我的应用程序与几乎所有模拟
  • Linq.Select() 中的嵌套表达式方法调用

    I use Select i gt new T 每次手动点击数据库后将我的实体对象转换为 DTO 对象 以下是一些示例实体和 DTOS 用户实体 public partial class User public int Id get set
  • 使用 C# 动态创建按钮并按预定义的顺序放置它们

    NET 4 5 C 创建 Windows 窗体 我想动态创建和添加按钮并为其分配单击事件 但希望它们以特定的方式动态放置 就像图像一样 我的问题是如何以上述方式动态放置按钮 即 4x4 格式 一行 4 个按钮 4 列 但行数不受限制 是否可
  • SQL Server“未找到网络路径”在不同环境中随机且不频繁地发生

    类似 如果不是同一个问题 随机遇到网络路径未找到异常 https stackoverflow com questions 38696448 network path not found exception encountered rando
  • C++ Boost ASIO 简单的周期性定时器?

    我想要一个非常简单的周期性计时器每 50 毫秒调用我的代码 我可以创建一个始终休眠 50 毫秒的线程 但这很痛苦 我可以开始研究用于制作计时器的 Linux API 但它不可移植 I d like使用升压 我只是不确定这是否可能 boost
  • 嵌入式二进制资源 - 如何枚举嵌入的图像文件?

    我按照中的说明进行操作这本书 http www apress com book view 9781430225492 关于资源等的章节 我不太明白的是 如何替换它 images Add new BitmapImage new Uri Ima

随机推荐