Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Not defined as function or array" while compiling

I have inherited some old code where each function is defined as an individual file. I am attempting to write a simple program to test this. I have written test.f a program that at its base calls the function in func.f and then reports the result.

Using ifort -c func.f I created the object file for func.f and then attempted to compile using ifort test.f func.o -o test. This gives me the error that func is not defined as a function or array. Any thoughts?

test.f is

      PROGRAM test
      REAL :: X,Y
      REAL :: FUNC
      X = 1.0
      Y = func(X)
      WRITE(6,*) X
      END

and func.f is

      FUNCTION func(X)
      func = X
      RETURN
      END
like image 628
Daniel Young Avatar asked Aug 11 '26 14:08

Daniel Young


1 Answers

A type declaration statement like

real func

declares that there exists an entity with name func. This may be either:

  • a function with real result; or
  • a variable of type real

In isolation, from just this declaration, it is not possible to determine which type of entity func is.

If func is not declared an array and there is no other use of func in the scope which is inconsistent with it being a function, then func is taken to be a function by any reference where it can be a function, such as

real func
print *, func(1)
end

In the absence of an array declaration for func, any use of func in the scope which is inconsistent with func a function will be an error. ifort will generally issue an error message in such case looking like

 error #6410: This name has not been declared as an array or a function.

What uses of func in a scope would be inconsistent with func a function? Just about anything that doesn't look like f(...) in an expression. For example:

  • giving func some attribute a only variable may have
  • using it as a variable in an assignment statement1
  • providing explicit initialization
  • using its name when a reference is required
  • etc.
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

(All of these uses are consistent with being an array, we just haven't declared it as such.)

Some type declaration statements make it obvious the entity must be a variable:

real :: not_func = 1.
real, allocatable :: definitely_variable
real :: definitely_array(5)

end

That's all to say: if you intend to use real func to declare an external function func with implicit interface and real result, but you get a warning about "not an array or function" when you try to reference it then you've got something somewhere which means func isn't a function and you haven't said it's an array.

It could be quite boring to check for all cases where func could be misused, so let's make our life easier:

real, external :: func

Although without the external attribute specification the EXTERNAL attribute is applied if func is a function, there's certainly no harm it using it. Indeed, it's good: this way we've told the compiler that func really is a function. Which means that any use of func inconsistent with being a function is an error, instead of the function reference.

Try the previous example with external added.

You can also be precise about func being an external function using an interface block (good practice) or a procedure declaration statement.


1 Although a function reference can be a variable, like in

func(1) = 12   ! func a function not an array

this is only the case when the function result is a pointer. A function with implicit interface cannot have a pointer result so this use is not consistent with func a function. We should also avoid confusion with the statement function

real :: func
func(i) = i+1

This is consistent with func a function, but it's not an external function defined elsewhere.

like image 119
francescalus Avatar answered Aug 14 '26 10:08

francescalus



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!