无法抑制绑定检查

Unable to suppress bound checking

首先,我不知道使用 gfortran 时绑定检查是自动的。使用以下代码:

gfortran -Wno-array-bounds initial_parameters.f08 derrived_types.f08 lin_alg.f08 constitutive_models.f08 input_subs.f08 Subprograms.f08 mainprog.f08 

我仍然收到编译时警告:

Warning: Array reference at (1) is out of bounds (3 > 2) in dimension 2

我可能在这里很傻,但是从阅读 this 后,我认为 -Wno-array-bounds 应该抑制这个警告?使用 -w 编译成功禁止所有警告。

我不知道它是否相关,但这些警告的来源是 "Subprograms.f08" 和 "constitutive_models.f08",它们都是包含子例程的模块,并在主程序中使用。

如果我尝试使用

编译单个模块,则会发生相同的行为
gfortran -Wno-array-bounds -c constitutive_models.f08 

所以我可能建议使用重载子例程来处理数据 - 然后您将拥有通用行为,而无需将维度参数显式传递给函数(从而消除警告)。然后我会建议您遵循 Holmz 关于在测试阶段使用所有警告然后在生产构建 (-w) 期间完全关闭它们的建议。现在我无法找到一种有效的方法来抑制这个警告(除了-w) - 似乎默认情况下对数组边界的检查是打开的并且没有被覆盖 -fno-bounds-check 或 -Wno-array -界限。但是重载函数可以更好地解决您的问题,在这种情况下实现应该如下所示:

module functions

    implicit none

    interface test_dim
        module procedure test_func1d, test_func2d, test_func3d
    end interface ! test_dim

    contains

    subroutine test_func1d(input1d)
        real, intent(in) :: input1d(:)

        print*, "DOING 1 DIM"
        print*, "SHAPE OF ARRAY:", shape(input1d)
    end subroutine test_func1d

    subroutine test_func2d(input2d)
        real, intent(in) :: input2d(:,:)

        print*, "DOING 2 DIM"
        print*, "SHAPE OF ARRAY:", shape(input2d)
    end subroutine test_func2d

    subroutine test_func3d(input3d)
        real, intent(in) :: input3d(:,:,:)

        print*, "DOING 3 DIM"
        print*, "SHAPE OF ARRAY:", shape(input3d)
    end subroutine test_func3d

end module functions

program test_prog
    use functions

    implicit none

    real :: case1(10), case2(20,10), case3(30, 40, 20)

    call test_dim(case1)
    call test_dim(case2)
    call test_dim(case3)
end program test_prog

此函数产生的输出如下所示:

 DOING 1 DIM
 SHAPE OF ARRAY:          10
 DOING 2 DIM
 SHAPE OF ARRAY:          20          10
 DOING 3 DIM
 SHAPE OF ARRAY:          30          40          20

我可以用这个简单的代码确认 compile warning with gfortran (4.4):

 integer,parameter::dim=3
 integer :: x(2)
 if(dim.eq.1)write(*,*)x(dim)
 end

Warning: Array reference at (1) is out of bounds (3 > 2) in dimension 2

这可以说是一个错误,因为人们希望编译器优化整个 if 语句。注意 ifort 可以很好地编译它。

一个非常简单的解决方法修复了这个例子:

 integer,parameter::dim=3
 integer :: x(2),dimx=dim
 if(dim.eq.1)write(*,*)x(dimx)
 end

当然,因为它只是一个警告,而且您知道这不是问题,所以您也可以选择忽略它!

注意参数在逻辑中的使用,以防编译器稍后想要优化它。