英文:
Fortran argument omitted via two consecutive commas (,,) - replace for use with explicit interface
问题
我正在使用一个旧的Fortran代码,其中使用类似这样的子程序调用:
call sub(A,,C)
相应的子程序形式如下:
subroutine sub(A,B,C)
因此,在实践中,参数B在这里是可选的。
然而,我现在通过编译器选项/warn:interface /gen-interface创建显式接口,以便调试代码中的接口错误。这会导致以下错误(来自Intel Visual Fortran编译器19.1.0057.16):
error #8127: 在调用定义了显式接口的Fortran例程时,不允许使用空参数。 [sub]
我可以将参数B设为可选,并将其移到参数列表的末尾。这将涉及更新许多函数调用。此外,我不确定它是否在一般情况下有效,因为例如,不同函数调用可能以不同的方式省略多个参数的组合。
如何正确现代化上述代码以使其与显式接口正常工作的方法是什么?
英文:
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.
答案1
得分: 1
Compaq Fortran for OpenVMS manual(Compaq Fortran是Intel Fortran的前身,但OpenVMS是一个不同的操作系统)提供了以下信息:
> 如果您不想为必需参数指定值,可以通过在参数列表中插入逗号 (,)
作为占位符来传递一个空参数。如果例程需要除默认传递机制之外的传递机制,您必须在CALL
语句或函数调用中指定传递机制。
我理解这个特性在调用其他编程语言中创建的过程时可能非常有用,例如各种系统调用或其他调用C语言编写的过程。Compaq Fortran手册中也提供了一些示例。您还可以在VSI Fortran for OpenVMS manual中找到相关信息。
Oracle Fortran manual 将其称为Fortran 77功能,可通过 -f77 标志访问:
> 允许使用空实际参数。例如:CALL FOO(I,,,J)
在第一个 I
和最后一个 J
参数之间有两个空参数。
但这并不是合法的Fortran语法。在底层,将传递一个空指针而不是实际参数的地址。
现代化的方法是使用Fortran 90及更高版本并使用可选参数。
subroutine sub(A,B,C)
...
real, optional :: B
在Fortran 2018中,也可以用于使用Fortran-C互操作性和bind(C)
编写的其他编程语言的过程。您需要在此类过程的接口块中适当定义它。
具有未提供参数B的实际参数的调用如下:
call SUB(A_actual,C=C_actual)
这些是命名("关键字")参数,也是Fortran 90引入的。您还可以在所有实际参数都存在时使用它们。
例如,https://stackoverflow.com/questions/25655171/fortran-90-function-with-no-arguments?noredirect=1&lq=1 https://stackoverflow.com/questions/7480712/how-does-fortran-interact-with-optional-arguments
英文:
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., https://stackoverflow.com/questions/25655171/fortran-90-function-with-no-arguments?noredirect=1&lq=1 https://stackoverflow.com/questions/7480712/how-does-fortran-interact-with-optional-arguments
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论