Closing if-loops by "endif" vs. "end if"

When writing a conditional loop, one functional pattern is

if (angle < 90.0) then
  print *, 'Angle is acute'
end if

However, so far, I did not notice a functional difference with

if (angle < 90.0) then
  print *, 'Angle is acute'
endif

with endif, without a space between end and if. (Similar to this, do iterations closed by either end do, or enddo.)

Is backward compatibility to FORTRAN a reason why Fortran permits both approaches to convey the (apparently) same instruction?

At present (excluding this post), posts in this forum prefer the separated form:

  | keyword  | instances |
  |----------+-----------|
  | "endif"  |        32 |
  | "end if" |       50+ |
  |----------+-----------|
  | "enddo"  |        27 |
  | "end do" |       50+ |
  |----------+-----------|

This and end if (with space) being used in fortran-lang’s quickstart tutorial suggest it either is just more popular (within this population). Or, is it today’s recommended approach for writing anything new in Fortran?

1 Like

There is no difference between ENDIF and END IF. Both are valid.

I looked into the FORTRAN 77 standard and it is written END IF. In the Fortran 2018 standard I found only three occurrences of ENDIF, which means the END IF version is preferred.

3 Likes

Indeed, the modern way is to put space in it.

These are one of the things I am hoping the “opinionated modern” (pedantic/strict) mode in LFortran (#450) would simply warn against, so if you use endif, you would get a warning to use end if. That way it would help users to converge on the modern style.

4 Likes

Can you add a style warning for REAL(4) and the like please?:smiley:

5 Likes

The requirement to have if/do to appear after end seems rather redundant. I personally prefer to have if/do in closing a block/loop as it significantly improves readability. But I have also seen users and critiques counting this verbosity as a Fortran weakness. This argument is absolutely baseless, in my opinion. But at the same time, I do not understand why the presence of if/do following an end is mandatory in Fortran. Compilers should not have trouble decoding the meaning of an end as opposed to end if or end do.

1 Like

I put it on the list. Thanks!

5 Likes

Fortran’s function have many forms

   !> form 1
    function foo()
        integer::foo
    end function foo
  !> form 2
    integer function foo()
    end function foo
  !> form 3
    integer function foo()result(res)
    end function foo
   !> form 4
    function foo()result(res)
        integer::res
    end function foo

Is it possible to delete any forms and just keep one form(may in strict mode)?

I prefer form 4, because its return value is clearer than form 1,and if the return value is an array, form 2 and form 3 must write statement like dimension(n,n)::res, Thanks!

4 Likes

I agree, and that is what the F subset supports – see R1217, and also ELF90, I think. A starting point for a modern Fortran subset could be F plus what was added in the Fortran 2003 and later standards.

1 Like

It is possible and I added it to the list. I prefer the form 3 usually, but for arrays I use the form 4. I agree that it is quite confusing to newcomers the 4 different ways of writing a function, and reducing this number would help if we can all agree on one or two forms.

1 Like

We need a way of differentiating between the different meanings of END.

In Fortran 77, “… an END statement is also an executable statement and must appear only as the last statement of a program unit”.

Modern Fortran does not require the keywords PROGRAM, SUBROUTINE, etc., after an END statement that terminates a program unit. How do you then differentiate between an END statement that means “return” and an END statement that ends an IF block, etc.?

1 Like

Matlab has been around for more than 40 years, and you still think end if and end do are impossible to write as just end?

There are actually some ambiguities with regards to parsing of end, I don’t know if they are solvable or not in this case. Anything can be done with a backtracking parser or more than one look ahead. But it is also important to ensure parsing is fast. We would have to prototype it and see.

1 Like

I personally write in the most verbose possible style in any programming language for clarity and readibility. I think it is possible to avoid the labels if needed/wanted. MATLAB is an example, as fortran4r mentioned. But I get your point (which appears in line with Certik’s concerns). The end word is a reserved keyword in MATLAB and cannot be used as a variable name. There is no reserved keyword in Fortran, which is great, but it could create ambiguities, although I doubt if it really does. It certainly makes parsing more difficult for the compilers.

3 Likes

Well, we could use braces (’{}’ ) instead of begin and end, but such changes to the language have to be proposed, discussed and accepted. If these changes cause large bodies of existing F77 and older codes to become invalid, there will be a need for compilers to have a legacy mode (or option) to enable these older codes to remain compilable.

Matlab as a programming language has many irregularities, some of which may become major issues when ported to a compiled language. For example, the effective name of the first function in an m-file is taken from the file name and not the declaration of the function.

-std=legacy of gfortran? Or one could even keep everything as before, but enforce the latest semantics when -std=f202x is specified, until all codebases catch up. Intel compiler used to default to Fortran <2003 semantics until around 2015 (when I and perhaps many others like me began to criticize the Intel compiler’s tradition in the Intel forum).

I find the supreme oddity of MATLAB to be the fact that everything is a 2D matrix, by default.

I write utility programs in C sometimes. After reading the comments above regarding END IF versus END in Fortran, I remembered the many occasions where a missing or misplaced ‘}’ caused the C compiler to issue mystifying error messages.

Here is a part of the C source for function nqueens from Rosettacode. Near the end of the function, we see a number of closing braces. I have added comments to indicate what construct it is that a particular ‘}’ terminates.

          } // end if
        }   // end while
        posib = posibs[--d]; // backtrack ...
      } // end while
    }   // end for
  }     // end for
  return num*2;
}       // end function

If one of those braces was missing, and the code was not properly indented, or there were additional statements between successive ‘}’ s, would the error messages from the C compiler tell the programmer where to place the missing ‘}’?

2 Likes