Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28862 Discussions

redefining a do loop index inside a do loop

andrew_4619
Honored Contributor III
712 Views

I just spent a while chasing a puzzling bug, and made a simple  code to demonstrate. Clearly it is not legal Fortran  but is is reasonable to expect the compiler to complain (it doesn't)?

program testcontains
    implicit none
    integer :: l1
    do l1 = 1 , 2 
        call tester()
        print *,'main',l1
    enddo
    contains
    subroutine tester()
        do l1 = 1, 4
            print *,'tester',l1
        enddo
    end subroutine tester
end program testcontains

The result is:

tester 1
tester 2
tester 3
tester 4
main 5

because l1 is illegally redefined within the do loop. I am unsure if the complier is required to complain or not I guess that depends if there is a specific constrain in the standards.

Declaring L1 as integer within tester() fixes the problem as l1 then becomes local.

0 Kudos
1 Solution
Steve_Lionel
Honored Contributor III
701 Views

No, the standard does not require a compiler to complain about this.  I tried it with NAG Fortrtan and it offered:

Questionable: t.f90, line 10: DO index variable L1 is not a local variable (it is from host TESTCONTAINS)

It would be great if /warn:usage in the Intel compiler would do something similar, but of course that would require you to specify it.

View solution in original post

0 Kudos
5 Replies
Steve_Lionel
Honored Contributor III
702 Views

No, the standard does not require a compiler to complain about this.  I tried it with NAG Fortrtan and it offered:

Questionable: t.f90, line 10: DO index variable L1 is not a local variable (it is from host TESTCONTAINS)

It would be great if /warn:usage in the Intel compiler would do something similar, but of course that would require you to specify it.

0 Kudos
jimdempseyatthecove
Honored Contributor III
687 Views

Steve,

Something else may be exposed by this simple (ill formed) test program.

The do loop statement (is to) produce a trip count based upon the statement's initial conditions.

Line 4 of the example code should have created a trip count of two (as opposed to a limit test of its scoped l1 <=2).

The resultant code showed  (implied) that a limit test was performed as opposed to a trip count (unless the compiler generated a shared variable/register for use as a trip count, which would also be an error in code generation).

 

Comments?

 

Jim Dempsey

0 Kudos
Steve_Lionel
Honored Contributor III
676 Views

The standard says that a DO loop calculates a trip count at the beginning. Any changes to the index variable inside the loop result in undefined behavior. I believe that if the Intel compiler detects a possible modification of the index variable, it switches to a tested loop - at least that was the behavior in the DEC days for compatibility with old code that did this, and from your observation that still seems to be happening. Non-standard code produces undefined behavior.

0 Kudos
jimdempseyatthecove
Honored Contributor III
671 Views

Right about the trip count. The point I was trying to make was that, the output of the test program shows the printing of "main ..." once, not twice as the trip count would perform. While the code is expected to have undefined behavior, I suspect that the missing trip count run is indicative of a different problem, which should be looked at.

 

Jim Dempsey

0 Kudos
Steve_Lionel
Honored Contributor III
663 Views

There is no problem with the compiler - it is behaving as designed. It sees that there is a procedure call in the loop which could potentially modify the index variable, and then changes to a tested loop.

I wrote about the perils of unexpected uplevel references at Doctor Fortran in "Think, Thank, Thunk" - Doctor Fortran (stevelionel.com)

0 Kudos
Reply