Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Gfortran present() function not working as expected 1

Status
Not open for further replies.

isotoper

Programmer
Jun 11, 2012
2
GB
I am using Gfortran 4.4.3 on Ubuntu 10.04 operating system.
Can someone explain why the following code works correctly (a):-

program testpresent
real :: a,b,c
call test_present(a,b,c)
contains
subroutine test_present(x1,x2,x3,x4,x5,x6)
real, intent(inout), optional :: x1,x2,x3,x4,x5,x6
write(6,*) present(x1),present(x2),present(x3),present(x4),pr esent(x5),present(x6)
return
end subroutine test_present
end program

works correctly (T T T F F F) while (b):-

program testpresent
real :: a,b,c
call test_present(a,b,c)
end program

subroutine test_present(x1,x2,x3,x4,x5,x6)
real, intent(inout), optional :: x1,x2,x3,x4,x5,x6
write(6,*) present(x1),present(x2),present(x3),present(x4),pr esent(x5),present(x6)
end subroutine test_present

does not. There is nothing in the documentation that says (b) is wrong, and it compiles without error messages.

Any advice would be much appreciated.
 
ifort 12.1.0 compiles with no error message and gives the answer TTTFFF
gfortran 4.6 does not compile, gives the following error message
Code:
present.f90:3.17:

call test_present(a,b,c)
                 1
Error: Dummy argument 'x1' of procedure 'test_present' at (1) has an attribute that requires an explicit interface for this procedure
 
Thank you for investigating. Clearly different compilers apply the F90 standard differently, but at least gfortran 4.6 gives an error message.
 
Clearly different compilers apply the F90 standard differently

No : your conclusion is just plenty wrong. The two compilers apply the same standard. But your version b) is just non standard : you call the external routine test_presence using the default standard interface (i.e. three non optional arguments) while that routine really expects six optional arguments.

As the main program and the subroutine may be compiled independently, a normal compiler may not identify this kind of bug.

François Jacq
 
I do support Francois in that the compilers apply the same standard - but the non-standard thing is not the call of the routine with three instead of six arguments, for they are declared optional in the called routine. But the way of the call is completely different in both examples.

In the first, the subroutine is attached to the main program by a contains-statement. This makes it an internal procedure that does not have a datastructure of its own unless you declare variables in the routine. So if you want to have x1 to x6 available in test_parent, you would not even have to include these items into the argumentlist. For the subroutine is part of the same program unit as the main program, the compiler knows of the data structures to be expected and knows about how the datatypes are declared there if any at all.

Whereas in your second example main and subroutine are two seperate program units with seperate data structures. You have to make x1 to x6 explicitly available to the subroutine if you want to use them there. According to my documentation however the optional-attribute requires that you do explicit interfacing, otherwise it would not work. For what reason ever the compiler needs this information during compilation of the main program (for errorchecking ?). That is what the errormessage is telling you.

So your code should look like this

Code:
program testpresent

interface
    subroutine test_present (x1, x2, x3, x4, x5, x6)
    real, intent(inout), optional :: x1,x2,x3,x4,x5,x6
end interface

real :: a,b,c
call test_present(a,b,c)
end program

subroutine test_present(x1,x2,x3,x4,x5,x6)
real, intent(inout), optional :: x1,x2,x3,x4,x5,x6
write(6,*) present(x1),present(x2),present(x3),present(x4),pr esent(x5),present(x6)
end subroutine test_present

This compiles and runs and brings the result T T T F F F as expected.
Hope this explains the difference a little.


Norbert



The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true.
 
Ah, forgot to mention:
So it is not that the compilers do apply the standards differently but they differ in the checking for errors and their treatment.

Norbert


The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true.
 
Sorry, the code I added was not the last version and has an error [blush]

Code:
program testpresent
interface
    subroutine test_present (x1, x2, x3, x4, x5, x6)
    real, intent(inout), optional :: x1,x2,x3,x4,x5,x6
    end subroutine   !  <<<< ------- this is needed !
end interface

real :: a,b,c
call test_present(a,b,c)
end program

subroutine test_present(x1,x2,x3,x4,x5,x6)
real, intent(inout), optional :: x1,x2,x3,x4,x5,x6
write(6,*) present(x1),present(x2),present(x3),present(x4),pr esent(x5),present(x6)
end subroutine test_present
[/blush]

Norbert


The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top