0

Firstly, I wasn't aware that bound checking was automatic when using gfortran. With the following code:

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

I still receive the compile time warnings:

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

I am probably being silly here but from reading this, I thought that -Wno-array-bounds was supposed to suppress this warning? Compiling with -w successfully inhibits all warnings.

I don't know if it's relevant but the source of these warning are "Subprograms.f08" and "constitutive_models.f08" which are both modules containing subroutines and are used in the main program.

The same behaviour occurs if I attempt to compile an individual module with

gfortran -Wno-array-bounds -c constitutive_models.f08 
francescalus
  • 30,576
  • 16
  • 61
  • 96
1QuickQuestion
  • 417
  • 6
  • 16
  • It's unusual to build gfortran with -fbounds-check set as default. Your compile time checking is a different issue which you should fix in the source code. – tim18 Sep 16 '16 at 16:11
  • I didn't build gfortran, I installed it simply using `sudo apt-get install gfortran` on Ubuntu 16.04. Surely this indicates that there must be something up with the source code. I'll try removing gfortran and reinstalling it - this made no difference. – 1QuickQuestion Sep 16 '16 at 16:15
  • It probably doesn't suppress the check at compile-time. Bounds checking would always be good to use, except for increased run time. Compilers and computers are now so fast, why worry about increased compile time? – M. S. B. Sep 16 '16 at 20:12
  • 1
    If it common to use bounds checking, initialised variable checking, and unused variable checking during development. Once you have either unit tested, or run against some standards which give expected results, then code is recompiled without those checks and a final verification of 'rightness' is confirmed. Then the production code is released with -O2, -O3 etc. One certainly wants to correct the out of bounds issues, rather than just disabling the bounds warnings. – Holmz Sep 17 '16 at 08:45
  • 1
    I have written a code which can work in 1, 2 or 3 dimensions depending on the specification in a modules which contains the simulations parameters. Hence there are branches of code which depends on the number of dimensions selected. Consequently if a lower dimension is selected warnings are generated at compile time. For example `ELSEIF (dim==3) THEN particle_data(jj)%scnd_pk(dim-1,1) = particle_data(jj)%scnd_pk(1,dim-1)` where if `dim=1` this provokes the warning. – 1QuickQuestion Sep 19 '16 at 10:59

2 Answers2

3

I can confirm that compile warning with gfortran (4.4) with this simple code:

 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

this could arguably be considered a bug since one would expect the compiler to optimize out the whole if statement. Note ifort compiles this just fine.

a very simple workaround fixes this example:

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

of course since its just a warning, and you know its not a problem, you can choose to ignore it too !

note the use of the parameter in the logical, in case the compiler feels like optimizing it later.

agentp
  • 6,849
  • 2
  • 19
  • 37
2

So what I may suggest is to use overloaded subroutines in order to process the data - then you would have generic behavior without the need to pass the dimension argument explicitly to the function(thus getting rid of the warning). And then I would recommend you to follow Holmz's advice regarding using all warnings during testing stage and then completely turning them off during production build (-w). For now I wasn't able to find an efficient way of suppressing this warning (apart from -w) - it seems that the check for array bounds is on by default and is not overridden -fno-bounds-check or -Wno-array-bounds. But overloaded functions can be a better solution to your problem, the implementation should look like this in this case:

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

And the output produced by this function looks like this:

 DOING 1 DIM
 SHAPE OF ARRAY:          10
 DOING 2 DIM
 SHAPE OF ARRAY:          20          10
 DOING 3 DIM
 SHAPE OF ARRAY:          30          40          20
Chaosit
  • 1,116
  • 7
  • 21
  • 1
    Is this standard practice for this sort of problem? The problem is that the code is quite large with over 20-25 subroutines. Your suggestions essentially triples the number and means that any changes need to be made in 3 different subroutines which looks like a recipe for disaster to me! Although if this is common practice then I guess it's just a question of biting the bullet and being a better programmer. – 1QuickQuestion Sep 20 '16 at 09:53
  • I can't say for sure - I do not know the exactly your problem. In general - yes. But since you've mentioned that you have quite a lot of subroutines - this approach can be revised. First, do all those subroutines have similar signature? If yes - I would say that this can be a potential source of problems as well (at least it can be the source of confusion). If not - then you may try grouping them by the signature, creating the interface for each group. But if you can describe your problem in slightly more details - I may try to propose a specific solution. – Chaosit Sep 20 '16 at 11:43
  • Also interfaces are typesafe - if you call a function with a combination of arguments for which you have no implementation - then the compiler would complain about that – Chaosit Sep 20 '16 at 11:50
  • As @Chaosit mentioned it is common... But usually I find it works better for functions rather than subroutines. Since there are no solid examples it is hard to say exactly. One approach using DEC extensions, or ifort, is UNION and MAP, And then you can address and NxM 2D array as either 2D or a 1D (N*M). Pointers are another option, but they can be more problematic for vectorising code. So basically these functions, and any commonly used subroutines, can have the multiple versions which are best used in a library if they are used in a lot of programs. – Holmz Sep 22 '16 at 11:47