Any ideas on how to remove this goto statement?

sorry to ask but I simply cannot see how to remove this goto statement!

jkloop: do jk = 2, mtau - 3
                it = 0
 99             continue
                if (it >= 10) then
                    ...
                end if
                ...
                if (it > 0) then
                    ...
                    if (iconv == 0) then
                        it = 99
                        go to 99
                    end if
                end if
       
                if (igrv == 1) then
                    ...
                end if
                    
                ...

                if (iconv == 0) then
                    deltau = 0.5 * deltau
                    it     = it + 1
                    go to 99
                end if

                ...
    
                if (igrv == 1) then
                    ...
                end if
    
                ...
    
                if (iconv == 0) then
                    deltau = 0.5 * deltau
                    it     = it + 1
                    go to 99
                end if

                ...
    
                if (igrv == 1) then
                    ...
                end if
                    
                ...
    
                if (iconv == 0) then
                    deltau = 0.5 * deltau
                    it     = it + 1
                    go to 99
                end if

                ...
    
                if (igrv == 1) then
                    ...
                end if
    
                ...
    
                if (iconv == 0) then
                    deltau = 0.5 * deltau
                    it     = it + 1
                    go to 99
                end if
    
                ...

                if (igrv == 1) then
                    ...
                end if
                
                ...
                
                if (tau(jk) >= z23 .and. itau23 == 0) then
                    ...
                end if
        
                if (zk0 >= atmass1 .and. idelm == 0) then
                    ...
                end if
                    
                if (zk0 < atmass2) exit jkloop
        
                ...
        
                if (tau(jk) > z10) then
                    ...
                else
                    ...
                end if
      
            end do jkloop

Obviously the dots represent other lines of code. However, none of this code impacts the goto 99 parts.

Any suggestions appreciated.

Perhaps delete the 99 continue line, then change all the

go to 99

to

cycle

But you need to handle the it = 0 line a little bit.
Perhaps cycle and exit documentation below may help,

The goto and the label form a loop with a counter, therefore it is probably easiest to implement it with a proper do loop.

        jkloop: do jk = 2, mtau - 3
            it = 0
            iterations: do
                if (it >= 10) then
                    ...
                end if
                ...
                if (it > 0) then
                    ...
                    if (iconv == 0) then
                        it = 99
                        cycle iterations
                    end if
                end if
       
                if (igrv == 1) then
                    ...
                end if
                    
                ...

                if (iconv == 0) then
                    deltau = 0.5 * deltau
                    it     = it + 1
                    cycle iterations
                end if

                ...
    
                if (igrv == 1) then
                    ...
                end if
    
                ...
    
                if (iconv == 0) then
                    deltau = 0.5 * deltau
                    it     = it + 1
                    cycle iterations
                end if

                ...
    
                if (igrv == 1) then
                    ...
                end if
                    
                ...
    
                if (iconv == 0) then
                    deltau = 0.5 * deltau
                    it     = it + 1
                    cycle iterations
                end if

                ...
    
                if (igrv == 1) then
                    ...
                end if
    
                ...
    
                if (iconv == 0) then
                    deltau = 0.5 * deltau
                    it     = it + 1
                    cycle iterations
                end if
    
                ...

                if (igrv == 1) then
                    ...
                end if
                
                ...
                
                if (tau(jk) >= z23 .and. itau23 == 0) then
                    ...
                end if
        
                if (zk0 >= atmass1 .and. idelm == 0) then
                    ...
                end if
                    
                if (zk0 < atmass2) exit jkloop
        
                ...
        
                if (tau(jk) > z10) then
                    ...
                else
                    ...
                end if
                exit iterations
            end do iterations
        end do jkloop

I can’t simply do cycle, because the goto deliberately does not increment jk.

Oh, I love this solution! Thank you so much!
It’s everything I was looking for and could not think of.

Again, thank you.

As a first fix to get rid of a goto/label, the one-trip do loop is always a good starting point.

Legacy code like this

 42 continue
    ...
    if (cond) goto 42
    ...

becomes

label: do
    ...
    if (cond) cycle label
    ...
    exit label
end do label

The exit/end do combination serves as a proper reminder to refactor this piece of code further ;).

2 Likes

In the code that you posted, the integer variables mtau, igrv, iconv, itau23, idelm and the real variable atmass1, atmass2, z23 and zk0 are never changed (unless that happens in the lines of code that you represented by “…”). If they are constants, you could declare them as parameters, and most of the IF…THEN blocks inside the loop can either be removed or the IF and THEN surrounding those brackets can be removed.

After declaring IGRV and ICONV as constants, with values 1 and 6, I ran one compiler on the code and was told a dozen times that “This IF statement is redundant as it will never succeed”.

I feel that the existing code is needlessly complicated, with so many conditional statements and repeated blocks of code, all inside a long loop. It is difficult to understand, and may be difficult to debug.

You are correct in that the variables are all altered within this loop. The missing lines are complex and considerable in number, adding nothing to my post; hence why I removed them.

The code is complicated and since my function in this is to understand how this code works, you can imagine how challenging this has been. However, though I am altering where there are obvious concerns (either redundant code, loops that can be combined, the removal of gotos and similar jumps, etc), this is not the major thrust of my PhD and I really should be focussing less on the code now and more on the astrophysics part! Hahahaha!

The compiler and software tools can help you with that, with a little bit of cooperation.

If the compiler tells you that certain blocks of code will never be executed, those blocks are items that you do not need to debug or worry about.

On the other hand, if you expected those blocks to be really used and do something useful, the warnings from the tools can help you to fix the code so that it faithfully simulates the part of the universe that you ask it to.

I need to learn more of the compiler command line instructions :slight_smile: