我继承了一些旧代码,其中每个函数都被定义为一个单独的文件。我正试图写一个简单的程序来测试这一点。我有笔试。一个程序在它的基础上调用函数中的函数。F,然后报告结果。
使用ifort -c func.f
,我创建了func的目标文件。f,然后尝试使用ifort test.f func.o -o test
编译。这给了我一个错误,即func没有定义为函数或数组。任何想法吗?
测试。f是
PROGRAM test
REAL :: X,Y
REAL :: FUNC
X = 1.0
Y = func(X)
WRITE(6,*) X
END
和函数。f是
FUNCTION func(X)
func = X
RETURN
END
类型声明语句
real func
声明存在名称为func
的实体。这可以是:
- 一个具有真实结果的函数;或
- 一个real类型的变量
单独地,仅从这个声明中,不可能确定func
是哪种类型的实体。
如果func
没有被声明为数组,并且func
在作用域内没有其他用途,这与它是一个函数不一致,那么func
被任何可以作为函数的引用视为函数,例如
real func
print *, func(1)
end
在func
没有数组声明的情况下,如果func
在作用域中与func
函数不一致,则会产生错误。在这种情况下,Ifort通常会发出一个错误消息,看起来像
error #6410: This name has not been declared as an array or a function.
在作用域中func
的哪些用法与func
在函数中的用法不一致?表达式中任何看起来不像f(...)
的东西。例如:
- 给
func
一些属性一个唯一的变量可能有 - 将其用作赋值语句中的变量1
- 提供显式初始化
- 在需要引用时使用其名称
- 等。
real :: func ! Function or variable?
save func ! Function can't be SAVEd
func = 1 ! Function name can't be on the left-hand side
print *, func ! Function name can't be used in an expression
print *, func(1) ! Oops, func isn't a function.
end
(所有这些用法都与作为数组一致,我们只是没有这样声明它。)
一些类型声明语句使得实体必须是一个变量:
real :: not_func = 1.
real, allocatable :: definitely_variable
real :: definitely_array(5)
end
这就是说:如果你打算使用real func
来声明一个具有隐式接口和实际结果的外部函数func
,但是你得到一个"不是数组或函数"的警告;当你试图引用它时,你在某个地方得到了一些东西,这意味着func
不是一个函数,你没有说它是一个数组。
检查func
可能被滥用的所有情况可能会很无聊,所以让我们让我们的生活更轻松:
real, external :: func
虽然没有external
属性规范,但如果func
是一个函数,则应用EXTERNAL属性,使用它当然没有害处。事实上,这样做很好:这样我们就告诉编译器func
确实是一个函数。这意味着任何与函数不一致的func
使用都是错误的,而不是函数引用。
尝试前面添加external
的示例。
您也可以使用接口块(良好实践)或过程声明语句精确地确定func
是外部函数。
1虽然函数引用可以是变量,如
func(1) = 12 ! func a function not an array
只有当函数结果是指针时才会出现这种情况。具有隐式接口的函数不能有指针结果,因此这种用法与func
函数不一致。我们还应该避免与语句函数
real :: func
func(i) = i+1
这个与func
a函数一致,但它不是在其他地方定义的外部函数。