当前位置: C语言 -- 标准库 -- <fenv.h> -- FENV_ACCESS

FENV_ACCESS编译提示


概要:
#include <fenv.h>
#pragma STDC FENV_ACCESS on-off-switch

描述:

当程序可能访问浮点环境以测试浮点状态标志或者在非默认浮点控制模式下运行时,编译提示FENV_ACCESS提供了一种通知实现的方法。

编译提示FENV_ACCESS的目的是允许进行某些优化,这些优化可能会破坏标志测试和模式更改(例如:全局公共子表达式消除(global common subexpression elimination)、代码移动(code motion)、常量折叠(constant folding)等。)。通常情况下,如果编译提示FENV_ACCESS的状态为off,编译器认为默认模式生效,并且浮点状态标志不会被测试。


FENV_ACCESS编译提示指令可以出现在以下两个位置:

1、外部声明之外:编译提示指令的有效期从该指令开始直到编译单元结束或者遇到另一个FENV_ACCESS编译提示指令结束。

2、复合语句中所有显式声明和语句之前:编译提示指令的有效期从该指令开始直至复合语句结束或者遇到另一个FENV_ACCESS编译提示指令(包括在嵌套的复合语句中。)结束。复合语句结束后,编译提示的状态又会恢复到复合语句之前的状态。


如果程序测试浮点状态标志、设置浮点控制模式或者在非默认设置下运行,但编译时FENV_ACCESS编译提示的状态为off,这种行为是未定义的。FENV_ACCESS编译提示的默认状态是on还是off由实现定义。假设FENV_ACCESS编译提示状态为off时编译程序的A部分,FENV_ACCESS编译提示状态为on时编译程序的B部分;当执行从A部分传递到B部分时,浮点状态标志的状态是不明确的,浮点控制模式是默认设置。

on-off-switch值必须是ONOFF或者DEFAULT之一。


范例:
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
/*编译提示FENV_ACCESS范例*/

#include <fenv.h>
#include <stdio.h>

#pragma STDC FENV_ACCESS ON

void showExceptions(void)
{
    printf("Exceptions: ");
    /*判断是否设置浮点异常。*/
    if(fetestexcept(FE_ALL_EXCEPT)==0)
    {
        puts("No floating-point status flag is set.");
    }
    else
    {
    	/*判断设置的浮点异常。*/
        if(fetestexcept(FE_DIVBYZERO))
            printf("FE_DIVBYZERO ");
        if(fetestexcept(FE_INEXACT))
            printf("FE_INEXACT ");
        if(fetestexcept(FE_INVALID))
            printf("FE_INVALID ");
        if(fetestexcept(FE_OVERFLOW))
            printf("FE_OVERFLOW ");
        if(fetestexcept(FE_UNDERFLOW))
            printf("FE_UNDERFLOW ");
        puts("");
    }
    
    /*清除设置的浮点异常。*/
    feclearexcept(FE_ALL_EXCEPT);
}

void showRoundingDirection(void)
{
    printf("Rounding direction: ");
    switch(fegetround())
    {
    case FE_DOWNWARD:
        puts("FE_DOWNWARD");
        break;
    case FE_TOWARDZERO:
        puts("FE_TOWARDZERO");
        break;
    case FE_UPWARD:
        puts("FE_UPWARD");
        break;
    default:
        puts("FE_TONEAREST");
        break;
    }
}

void showFloatingPointEnvironment(void)
{
    showExceptions();
    showRoundingDirection();
    puts("");
}

int main(void)
{
    puts("Default floating-point environment:");
    showFloatingPointEnvironment();

    feraiseexcept(FE_DIVBYZERO | FE_OVERFLOW);
    fesetround(FE_DOWNWARD);
    puts("Current floating-point environment:");
    showFloatingPointEnvironment();

    return 0;
}


输出:

Default floating-point environment:

Exceptions: No floating-point status flag is set.

Rounding direction: FE_TONEAREST

 

Current floating-point environment:

Exceptions: FE_DIVBYZERO FE_OVERFLOW

Rounding direction: FE_DOWNWARD


相关内容:
FE_ALL_EXCEPT 表示所有异常的宏。
FE_DFL_ENV 表示默认浮点环境的宏。
FE_TONEAREST 表示就近舍入的宏。