【问题标题】:Does Java's strictfp modifier apply through function calls?Java 的 strictfp 修饰符是否适用于函数调用?
【发布时间】:2019-08-03 20:32:33
【问题描述】:

更准确地说,如果调用堆栈中存在带有strictfp修饰符的函数,那么调用堆栈顶部的函数是否也遵守strictfp修饰符?

public class Main {

    // case 1: strictfp not present at top of call stack
    private static double bar1(double x) {
        return Math.sin(x);
    }

    strictfp private static double foo1(double x) {
        return bar1(x);
    }

    // case 2: strictfp present at top of call stack
    strictfp private static double bar2(double x) {
        return Math.sin(x);
    }

    strictfp private static double foo2(double x) {
        return bar2(x);
    }

    public static void main(String[] args) {
        double x = 10.0;
        System.out.println(foo1(x)); // -0.5440211108893698
        System.out.println(foo2(x)); // -0.5440211108893698
    }
}

在此示例中,foo1foo2 似乎返回相同的值。换句话说,调用堆栈顶部的函数是否具有 strictfp 修饰符似乎并不重要,而更下方的函数也具有该修饰符。

这总是成立吗?如果我为x 选择不同的值怎么办?如果我选择正弦以外的浮点运算怎么办?

【问题讨论】:

  • 我认为strictfp 不适用于方法调用。我认为这是一个编译时间标志,以不同方式编译您的类和方法中的代码,它不会影响您调用的单独编译的代码。

标签: java floating-point strictfp


【解决方案1】:

JLS 15.4:

如果表达式不是常量表达式,则考虑所有包含该表达式的类声明、接口声明和方法声明。如果任何此类声明带有strictfp 修饰符(§8.1.1.3、§8.4.3.5、§9.1.1.2),则表达式为 FP-strict

[...]

因此,表达式不是FP-strict当且仅当它不是常量表达式并且它没有出现在任何具有strictfp修饰符的声明中。

因此,对外部方法或其他获取浮点表达式的方法的调用不会“继承”调用堆栈上某些东西的 FP 严格性。

【讨论】:

    猜你喜欢
    • 2011-03-11
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 2015-12-19
    • 1970-01-01
    • 2015-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多