Gcc 无法抑制绑定检查

Gcc 无法抑制绑定检查,gcc,fortran,compiler-warnings,gfortran,compiler-flags,Gcc,Fortran,Compiler Warnings,Gfortran,Compiler Flags,首先,我不知道在使用gfortran时绑定检查是自动的。使用以下代码: gfortran-Wno数组边界初始参数.f08驱动类型.f08 lin\U alg.f08构成模型.f08输入子程序.f08主程序.f08 我仍然收到编译时警告: 警告:维度2中(1)处的数组引用超出范围(3>2) 我在这里可能有点傻,但从阅读中,我认为-Wno数组边界应该抑制此警告?使用-w编译将成功禁用所有警告 我不知道这是否相关,但这些警告的来源是“Subprograms.f08”和“composition_mo

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

gfortran-Wno数组边界初始参数.f08驱动类型.f08 lin\U alg.f08构成模型.f08输入子程序.f08主程序.f08
我仍然收到编译时警告:

警告:维度2中(1)处的数组引用超出范围(3>2)
我在这里可能有点傻,但从阅读中,我认为
-Wno数组边界
应该抑制此警告?使用
-w
编译将成功禁用所有警告

我不知道这是否相关,但这些警告的来源是“Subprograms.f08”和“composition_models.f08”,这两个模块都包含子程序,并在主程序中使用

如果我尝试使用编译单个模块,也会出现相同的行为

gfortran-Wno数组边界-c构成_models.f08

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

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

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

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
我可以用以下简单代码确认使用gfortran(4.4)编译警告:

 integer,parameter::dim=3
 integer :: x(2)
 if(dim.eq.1)write(*,*)x(dim)
 end
警告:(1)处的数组引用超出维度2中的边界(3>2)

这可能被认为是一个bug,因为人们希望编译器优化整个
if
语句。注意:ifort编译得很好

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

 integer,parameter::dim=3
 integer :: x(2),dimx=dim
 if(dim.eq.1)write(*,*)x(dimx)
 end
当然,因为这只是一个警告,你知道这不是问题,你也可以选择忽略它

请注意逻辑中的参数用法,以防编译器以后想对其进行优化。

我可以用以下简单代码确认gfortran(4.4)的编译警告:

 integer,parameter::dim=3
 integer :: x(2)
 if(dim.eq.1)write(*,*)x(dim)
 end
警告:(1)处的数组引用超出维度2中的边界(3>2)

这可能被认为是一个bug,因为人们希望编译器优化整个
if
语句。注意:ifort编译得很好

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

 integer,parameter::dim=3
 integer :: x(2),dimx=dim
 if(dim.eq.1)write(*,*)x(dimx)
 end
当然,因为这只是一个警告,你知道这不是问题,你也可以选择忽略它


请注意在逻辑中使用参数,以防编译器以后想对其进行优化。

使用-fbounds检查集作为默认值构建gfortran是不常见的。编译时检查是另一个问题,应该在源代码中解决。我没有构建gfortran,我只是在Ubuntu 16.04上使用
sudo-apt-get-install-gfortran
安装它。当然,这表明源代码一定有问题。我将尝试删除gfortran并重新安装它-这没有什么区别。它可能不会在编译时抑制检查。边界检查总是好用的,除了增加运行时间。编译器和计算机现在速度如此之快,为什么还要担心编译时间的增加呢?如果在开发过程中经常使用边界检查、初始化变量检查和未使用的变量检查的话。一旦您进行了单元测试,或者运行了一些给出预期结果的标准,那么代码将在没有这些检查的情况下重新编译,并确认“正确性”的最终验证。然后,生产代码将与-O2、-O3等一起发布。人们当然希望纠正越界问题,而不仅仅是禁用边界警告。我已经编写了一个代码,它可以在1、2或3维中工作,具体取决于包含模拟参数的模块中的规范。因此,代码的分支取决于所选维度的数量。因此,如果选择较低的维度,则会在编译时生成警告。例如
ELSEIF(dim==3)然后particle\u data(jj)%scnd\u pk(dim-1,1)=particle\u data(jj)%scnd\u pk(1,dim-1)
其中如果
dim=1
这会引发警告。使用-fbounds复选框作为默认值构建gfortran是不常见的。编译时检查是另一个问题,应该在源代码中解决。我没有构建gfortran,我只是在Ubuntu 16.04上使用
sudo-apt-get-install-gfortran
安装它。当然,这表明源代码一定有问题。我将尝试删除gfortran并重新安装它-这没有什么区别。它可能不会在编译时抑制检查。边界检查总是好用的,除了增加运行时间。编撰