Ifort compiler error - do-variable within a DO body shall not appear in a variable definition context

Ifort compiler error - do-variable within a DO body shall not appear in a variable definition context

Hello,

            I have inherited this code and when I try to compile it I get the following error. Being a newbie to Fortran 90 I would appreciate any help

When I compile this code I get the message - do-variable within a DO body shall not appear in a variable definition context. I presume this code did compile with pgf90 (that is what the author of the code told me) but I am not sure why it does not compile with ifort.

Regards,

Ashwin.

do i=1,nz-1
         dh=aklev(i+1)-aklev(i)
         if (abs(dh-dz).gt.eps) then
            print*,'Aklev: Vertical grid must be equally spaced... Stop'
            print*,(aklev(i),i=1,nz)
            stop
         endif
         dh=aklay(i+1)-aklay(i)
         if (abs(dh-dz).gt.eps) then
            print*,'Aklay: Vertical grid must be equally spaced... Stop'
            print*,(aklay(i),i=1,nz)
            stop
         endif
      enddo

 

publicaciones de 6 / 0 nuevos
Último envío
Para obtener más información sobre las optimizaciones del compilador, consulte el aviso sobre la optimización.

This is a common f77 extension. Since 20 years ago you could write e.g. aklev (1:nz) and get rid of the implicit shadow scoped i.

This is definitely nonconforming, see 10-007.pdf, section 16.6.7, bullet point (4). data-implied-do or ac-implied-do don't change the value of the do variable, but io-implied-do does. As Tim points out, an array section could be used in this context to eliminate the do variable entirely, but sometimes the structure of what you want to read is such that you really need an io-implied-do. In such a case you could just change the name of the do variable to something else, like j, but given the possibility of implicit typing, you might be trampling on an innocent j out there someplace. A block construct here can preserve the context of your code and not trample on other variables:

         BLOCK
            integer i
            print*,(aklev(i),i=1,nz) 
         END BLOCK

 

RO's suggestion is a standard conforming way of accomplishing what that extension did with compilers which implemented it properly.  As he stated, it might be a source of unexpected failures if using a compiler which failed to diagnose it.  If a compiler supports recursive I/O (not such a widespread extension) it might also support this, but they fall into the category of dangerous extensions where there is no good way of determining at compile time whether it will work.

The interesting (to me, anyway) part of this question is that the do-variable in an io-implied-do does NOT have "statement scope" the way a DATA implied-do or array constructor implied-do variable do.  With statement scope, the implied-do variable is a new, different variable that inherits only the type of any outer-scope variable (but that type must be integer.)The "i" in the I/O implied DO is the same variable as the line 1 DO control variable and ifort is absolutely correct in complaining about this., pgf90 could support this as an extension, but would need to have the ability to diagnose it (perhaps through a standards checking switch), or else risk being a nonconforming implementation.

The other interesting part is that we do, sort-of, allow changing DO variables, as an extension, but you have to do it by passing the variable to a procedure which then changes it. ifort recognizes the possibility and generates an explicit test rather than a loop count if it sees this.

Retired 12/31/2016

The Fortran intrinsic function ANY can be used to express the desired check compactly, without the need for the DO loop. The first of the two tests for grid uniformity can be expressed as 

if (any(abs(aklev(2:nz)-aklev(1:nz-1)-dz).gt.eps)) then
    print ...
    stop
endif

 

Deje un comentario

Por favor inicie sesión para agregar un comentario. ¿No es socio? Únase ya