views:

49

answers:

2

I've written a function which calculates the eigenvalues of a 2*2 matrix. It takes a 2*2 matrix as an argument and returns 2 eigenvalues via a 2-element array. I have declared the function in the program unit like this:

real, dimension(2), external :: eigenvalues

But it won't compile, it comes up with this error:

Error: EXTERNAL attribute conflicts with DIMENSION attribute

Is it just not possible to have functions that return arrays, or am I doing something wrong?

Any help/suggestions are appreciated, thanks. If it helps, I'm using fortran 90 with the gfortran compiler

+1  A: 

The Intel Fortran compiler documentation tells me that EXTERNAL is incompatible with DIMENSION, which is roughly what your compiler is telling you. I've had a quick look at the standard for Fortran 2003 but have failed to interpret it unambiguously on this point -- so I'll agree with Intel and assert that what your are trying to do is non-standard.

You certainly can write functions which return arrays.

It looks a little odd to me that you have written the function EIGENVALUES and are then trying to declare it to be EXTERNAL. I would normally put my function definitions either in a CONTAINS section within a larger program unit or in a MODULE which the calling unit USEs. In neither case do I need to declare anything EXTERNAL.

Where is the source of EIGENVALUES wrt the source of the calling program ?

High Performance Mark
+1  A: 

Modestly extending the other two answers, I think other approaches are typically preferable to the old "external". (The "Fortran 2003 Handbook" lists at least one case in which "external" must be used.) As already suggested, for your own source code, place the procedures (functions & subroutines) into a contains section of a module and then use it. This will automatically make the interface of your procedures explicit so that the compiler can check compatibility between arguments in calls and the dummy arguments of the procedure -- this can catch a lot of programmer mistakes. If for some reason you don't have access to Fortran source code, for example, you are linking to a library or calling C, then I would write an interface statement describing the procedure. This will inform that compiler that the declared name is a function or program and specify the interface to allow argument check. I would only do this when the module method isn't possible because it is more work and prone to mistakes when changes are made because two items have to be changed.

Probably the reason this isn't working is, that according to the "Fortran 2003 Handbook", the use of the external attribute does not provide an explicit interface, and an explicit interface is required for a function returning an array argument. I don't know why the interface is considered to be non-explicit in this case.

M. S. B.