Yet another post ripped from the headlines of a user question, plus an earlier discussion in another Fortran-related group. The question at hand is: Does Fortran have any “reserved words”? These are identifiers that you must not use for your own variables, procedures, etc. The answer is…
No, it doesn’t. None at all. You can name things anything you like, subject to the normal constraints of an identifier name (per the standard, 31 characters, A-Z, a-z, 0-9, and underscore, starting with a letter – $ is an extension!) Want to name a variable REAL or GOTO or SQRT? Knock yourself out. The only rule that even begins to impinge on your freedoms here is that, in fixed-form source:
The program unit END statement shall not be continued. A statement whose initial line appears to be a program unit END statement shall not be continued.Fortran 2018 188.8.131.52
However, you can run into trouble here when it comes to intrinsic procedures, such as the aforementioned SQRT. Intrinsic procedures are predeclared, but you can hide them by declaring them with inconsistent attributes. For example:
integer :: sqrt
If you have this declaration in a program unit, this hides the intrinsic function SQRT. Similarly if you have a dummy argument named SQRT, that hides the intrinsic. But you are allowed to “reinforce” the type of an intrinsic without hiding it, so if you have:
That doesn’t hide the intrinsic. If you make a reference to an intrinsic that doesn’t match the predefined arguments, however, the compiler can assume that you don’t mean the intrinsic, so:
print *, sqrt(2)
would look for a user-supplied function called SQRT that has an integer dummy argument.
Where this can really get fun is if you have a scope where an intrinsic was overridden but, in an inner scope, you want to use that name as the intrinsic. For example:
real function f (x)
print *, sqrt(x)
end function f
end program whydididothis
The solution here is the INTRINSIC statement – add
intrinsic sqrt to function f and it can then use the intrinsic. (Fun historical fact – in FORTRAN IV (aka FORTRAN 66), the equivalent syntax was
EXTERNAL* – compilers with an F66 mode (such as Intel Fortran) enabled understand that.)
You can, of course, extend any of the generic intrinsics (such as SQRT) with a generic interface that defines a set of arguments not supported by an intrinsic. So let’s say you wanted to add an integer SQRT. You could do this:
integer :: int_sqrt
integer, intent(in) :: x
end function int_sqrtx
Now your reference to
sqrt(2) will be recognized and will call
int_sqrt (which you must provide), but
sqrt(2.0) will use the intrinsic.
Another tool at your disposal is EXTERNAL. This tells the compiler that the name is a procedure you are providing and to not recognize the intrinsic. This can be handy if you’re worried about the language (or a compiler extension) adding an intrinsic that has the same name as your procedure. Better, really, is to use an explicit interface, but EXTERNAL will do in a pinch.
Have a question or suggestion for Doctor Fortran? Leave a comment!