2016-09-16 75 views
0

首先,我不知道使用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 
+0

将gfortran与-fbounds-check设置为默认值并不常见。您的编译时检查是您应该在源代码中修复的另一个问题。 – tim18

+0

我没有构建gfortran,我使用Ubuntu 16.04上的'sudo apt-get install gfortran'来安装它。当然,这表明源代码必须有一些东西。我会尝试删除gfortran并重新安装它 - 这没有什么区别。 – 1QuickQuestion

+0

它可能不会在编译时压制检查。除了增加运行时间之外,边界检查总是很好用。编译器和计算机现在如此之快,为什么会担心增加编译时间? –

回答

3

我可以证实该编译警告与gfortran(4.4)与这个简单的代码:

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

警告:在(1)阵列参考超出范围(3> 2)的2维

这可以说是被认为是一个缺陷,因为人们期望编译器优化了整个if语句。注意ifort编译这个就好了。

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

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

因为它只是一个警告,你知道它不是一个问题,您可以选择忽略它呢!

注意在逻辑中使用该参数,以防编译器觉得稍后优化它。

+0

如果启用了绑定检查,Ifort也会发出警告。 –

+0

问题是,有相当多的警告似乎淹没了其他警告,可能有点更险恶。你的建议是一个很好的建议,并且帮助我去除了其中的大部分。 – 1QuickQuestion

2

发生

同样的行为因此,我可以建议是为了处理数据使用重载的子程序 - 那么你将有通用的行为,而不需要将维度参数明确地传递给函数(从而摆脱警告)。然后,我建议您遵循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 
+1

这是这种问题的标准做法吗?问题是代码很大,超过20-25个子程序。您的建议基本上将数量增加了三倍,意味着需要在3个不同的子程序中进行任何更改,这对我来说看起来像是一场灾难!虽然如果这是常见的做法,那么我想这只是一个咬子弹和做一个更好的程序员的问题。 – 1QuickQuestion

+0

我无法确定 - 我不知道你的问题。总的来说 - 是的。但是既然你提到你有很多子程序 - 这个方法可以修改。首先,所有这些子程序都有类似的签名吗?如果是的话 - 我会说这也可能是一个潜在的问题来源(至少它可能是混乱的根源)。如果没有 - 那么你可以尝试按签名对它们进行分组,为每个组创建接口。但是,如果您能够稍微详细地描述您的问题 - 我可能会尝试提出具体的解决方案。 – Chaosit

+0

另外接口是类型安全的 - 如果你用一个没有实现的参数组合调用一个函数 - 那么编译器会抱怨那个 – Chaosit