More problems with LBOUND and UBOUND

More problems with LBOUND and UBOUND

Ok, this pretty well nails it -

This simplified test case shows what happens when I have a lower dimension of ZERO,

for both the INPUT arrays AND the OUTPUT array. Using one dimensional arrays for simplicity.

Apparently the CALLED routine does not give the correct values for LBOUND and UBOUND.

It crashes thinking that the lower dimension is ONE, not Zero.

The upper dimension is also off by ONE, it should be 5, not 6.

BTW, the Fortran texts you referred to do not accurately portray the actual

behavior of the compiler, they portray the way it is SUPPOSED to work.

So, who is right?

If there is something subtle I missed, it sure never gets properly explained as far as I can tell.

Maybe the pre Fortran 95 approach would work better?

 

The problem goes away when I explicitly give the lower dimensions of ZERO.

AttachmentSize
Download test49_0.f90830 bytes
9 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

There are a few bugs in your program, in particular with regard to the proper bounds of array c in relation to those of a and b in the subroutine. Note, as well, that the lower bound of a dummy argument that is an assumed shape array is taken to be 1 if not explicitly specified, and not zero. See 5.3.8.3 of the Fortran Standard.

Since your program contains errors regarding dimensions and errors caused by passing/using assumed shape arrays without specifying the intended lower bound of 0 explicitly, many of your conclusions cannot be supported based on how the program runs. If you write programs without becoming familiar with the rules that govern a moderately complex language such as Fortran 9X/200X, you will continue to experience similar problems.

Here is a corrected version of your test program:

    module sumit_01
    contains
    subroutine sumit(a,b,c)
    real(8),intent(in) :: a(0:),b(0:)
    real(8),intent(out):: c(0:)
    integer na(1),nb(1),lbc(1),la(1),lb(1)
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    la=lbound(a);lb=lbound(b)
    print *,"la,lb=",la,lb
    na=ubound(a);nb=ubound(b)
    print *,"na,nb=",na,nb
    nc=na(1)+nb(1)+1
    lbc=lbound(c)
    print *,"lbc=",lbc
    do 1 ic=0,nc
1     c(ic)=0.d0
    do ia=0,na(1)
        do ib=0,nb(1)
            ic=ia+ib
            c(ic)=c(ic)+a(ia)*b(ib)
        end do
    end do
    end subroutine
    end module

    program test49
    use sumit_01
    real*8 a(0:20)/21*1.D0/
    real*8 b(0:20)/21*2.d0/
    real*8 c(0:20)
    call sumit(a(0:5),b(0:5),c(0:11))
    print 101,C(:11)
101 format("c="/(8F10.4))
    read(*,*)
    end

 

Well that is what I had before  and it worked OK

- but I thought you could omit the lower and upper bounds

of the called routine, and pass those in.

Isnt that the purpose of having assumed shape arrays?

Otherwise I could just say a(*),b(*), and c(*) and not have assumed shape arrays.

As soon as you EXPLICITLY put a lower bound, then they are NOT assumed shape arrays.

The whole point of this was to illustrate what happens with that particular feature of Fortran 95.

I was going by the textbooks, anyway.

Quote:

billsincl wrote:

As soon as you EXPLICITLY put a lower bound, then they are NOT assumed shape arrays.

Not true, as far as I know. Please provide authoritative references that support the above statement, and recognize an additional complication, namely, your using an array section for at least one of the actual arguments in the subroutine call. What should LBOUND, etc., return when applied to an array section (one that may be taken from the middle of an array and not including either end of the original array)? More generally, what should LBOUND, etc., return when applied to a dummy argument when the corresponding actual argument is an array expression?

This statement (the one quoted above) conflicts with the text of 5.3.8.3 of the Fortran standard, and with the text under "Assumed-Shape Specifications" in the Intel Fortran Reference Manual. https://software.intel.com/en-us/node/511005 (or see the installed manual on your PC).

Here is an even simpler example:

If I wanted Lbound =1 and Ubound =16, all I would have to do is say:

real a(*).

 

No need to use "assumed shape" arrays then.

According to what I read, the purpose of that is so I can get Lbound=15, and Ubound =30,

so as to agree with the calling routine.

 

Attachments: 

AttachmentSize
Download test50.f90261 bytes

Maybe the textbook has it wrong?

 

I will check the others.

OK, in the Metcalf text book (recommended I think by Steve)

page 100, it agrees with what i am saying here, namely that the dimensions of the

array in the CALLED routine agree with the dimensions of the CALLING routine.

This requires that I leave off ALL the dimensions in the CALLED routine.

 

Actually, later on in the textbook it agrees with what you said, namely, that

it does not pass upper and lower dimensions. But I don't see why one would ever have to use that feature, it seems

fine to just go ahead with the pre Fortran 95 approach. One could get the UPPER bounds by using the

UBOUND routine and explicitly declare the lower bounds to be ZERO.

Perhaps the following example will help. Try to reason out what the program should output, and then run the program to see if the result agrees with your expectations.

program xAssShpArr
integer :: x(2:7),i
x(2:7)=[(2*i+3,i=2,7)]

call sub1(x)
call sub2(x)

call sub1(x(2:5))
call sub2(x(2:5))

call sub1(x(3:7:2))
call sub2(x(3:7:2))

contains

  subroutine sub1(A)
  integer A(:)
  write(*,*)'Sub1 ',lbound(A),ubound(A)
  return
  end subroutine sub1


  subroutine sub2(B)
  integer B(0:)
  write(*,*)'Sub2 ',lbound(B),ubound(B)
  return
  end subroutine sub2

end program xAssShpArr

 

OK I will try that. Thanks ! !

Leave a Comment

Please sign in to add a comment. Not a member? Join today