Search code examples
fortran

Fortran argument omitted via two consecutive commas (,,) - replace for use with explicit interface


I'm working with an older Fortran code using subroutine calls like this:

call sub(A,,C)

With the corresponding subroutine of the form:

subroutine sub(A,B,C)

So in practice the argument B is optionally omitted here.

However, I am now creating explicit interfaces via the compiler options /warn:interface /gen-interface. I do this to debug interface errors in the code. This results in the following error (from Intel Visual Fortran compiler 19.1.0057.16):

error #8127: A null argument is not permitted when calling a Fortran routine which has an explicit interface defined. [sub]

I could make the argument B optional and move it to the end of the argument list. This would involve updating a lot of function calls. Also, I am not sure if it works in general, as e.g. several arguments may be omitted in this way in different combinations for different function calls.

What is the correct way to modernise the above code to work correctly with explicit interfaces?

Edit: The use of two consecutive commas (,,) is also a deprecated (?) language feature denoting a null data item. From the Oracle Fortran 77 language reference:

A null data item is denoted by two consecutive commas, and it means the corresponding array element or complex variable value is not to be changed. Null data item can be used with array elements or complex variables only. One null data item represents an entire complex constant; you cannot use it for either part of a complex constant.

In the comments below it was noted that this relates to the data input process, and does not apply to my problem.


Solution

  • The Compaq Fortran for OpenVMS manual (Compaq Fortran is a predecesor of Intel Fortran, but OpenVMS is a different operating system) has this:

    If you do not want to specify a value for a required parameter, you can pass a null argument by inserting a comma (,) as a placeholder in the argument list. If the routine requires any passing mechanism other than the default, you must specify the passing mechanism in the CALL statement or the function call.

    My understanding is that this feature would most likely be useful when calling procedures created in other programming languages. For example various system calls or other calls to procedures written in C. Such are also the examples offered by the Compaq Fortran manual. You can also see it in the VSI Fortran for OpenVMS manual.

    The Oracle Fortran manual calls this a Fortran 77 feature accessible with a -f77 flag:

    Allow null actual arguments. For example: CALL FOO(I,,,J) has two null arguments between the first I and the final J argument.

    But this is not and never has been legal Fortran. Under the hood a null pointer is passed instead if the address of an actual argument.

    The way to modernize it is to go to Fortran 90 and later and use optional arguments.

       subroutine sub(A,B,C)
         ...
         real, optional :: B
    

    In Fortran 2018 this can also be used for procedures written in other programming languages thanks to the Fortran-C interoperability and bind(C). One defines it appropriately in the interface block for such a procedure.

    The call with an actual argument with B not present looks like:

    call SUB(A_actual,C=C_actual)
    

    These are the named ("keyword") arguments, also introduced in Fortran 90. You can also use them when all actual arguments are present.

    E.g., Fortran 90 function with no arguments? How does FORTRAN interact with optional arguments?