Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29273 Discussions

Changing subroutines to functions (and vice versa) causes problems

WSinc
New Contributor I
595 Views
This seems to occur every time -

Program test
x=test1(n)
end

function test1(n)
......
......
end

The problem occurs if I decided to make the function a subroutine.
Even when I change it both in the routine and the calling program,
I get messages like:

Error - calling a subroutine as a function, or
Error - calling a function as a subroutine.

This happens even when I do a complete clean and rebuild from scratch.
The only way so far to avoid thse error messages is to change the NAME
of the routine, which is kind of annoying.

So apparently something gets saved in the interface information that does not
get cleaned up when I change the function to a subroutine, and even a CLEAN
doesn't get rid of it.

Try it yourself - I'm curious to see what happens on your end.
0 Kudos
4 Replies
aagaard
Beginner
595 Views
In your example you don't have any typefinition of the test1 function, neither in the calling program nor in the function decleration itself.
Have a look in the online documentation. I've copied one of the examples from documentation.

The following shows another example:

      INTEGER Divby2
10   PRINT *, 'Enter a number'
      READ *, i
      Print *, Divby2(i)
      GOTO 10
      END
C
C     This is the function definition
C
      INTEGER FUNCTION Divby2 (num)
      Divby2=num / 2
      END FUNCTION
0 Kudos
mecej4
Honored Contributor III
595 Views
>In your example you don't have any typefinition of the test1 function

Presuming that you meant "type definition" or "type declaration", we can quickly see that not declaring a type for the function "test1" is not the cause of any problems in the posted example.

Fortran has provision for implicit types and interfaces. The skeleton example that "billsincl" gave would make "test1" of type default real in both places, and there is no inconsistency there.

The real issue is how to avoid mixing up FUNCTION and SUBROUTINE subprograms and how to get help from the compiler in doing that.

Because Fortran allows separate compilation and subsequent linking, detecting such mistakes requires the cooperation of the programmer. Intel Fortran allows interfaces to be automatically generated from subroutine and function declarations. The compiler can use these generated interfaces to detect errors. If the programmer changes the source code and does not ensure that the compiler will create updated interfaces and use them for checking all routines that depend on these altered interfaces, the mismatch may not be detected at compile time. However, all this dependency analysis and recompiling consumes compilation time and is sometimes unneeded.

An undetected error will usually cause junk values to be used as function results if a subprogram declared as a subroutine is referenced as a function. The error can go undetected if the returned value is not noticeably incorrect, or the return value is simply stored and not used again.

The alternative is to emit sufficient code that the mismatch between caller and callee is detected at run-time. Some Fortran compiler choose this route. However, there is a run-time penalty.

In the end, it boils down to what the user wants the compiler do and what price is one is willing to pay, in terms of programmer time, compilation speed, execution speed and license fees.
0 Kudos
WSinc
New Contributor I
595 Views

However, there is a way to check the interfaces without incurring
a run-time penalty:

Have the LINKER do it. This avoids some of the problems implicit
in compiling routines in the wrong order. This of course assumes that
the source code routine are all compiled without error first.

At least we have some control in what order we can compile the routines.

I usually compile them one at a time when I make any changes.

0 Kudos
Steven_L_Intel1
Employee
595 Views
The linker doesn't have the necessary information. But there is no run-time penalty to having the compiler check.
0 Kudos
Reply