Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

The importance of not being explicit

51 views
Skip to first unread message

Clive Page

unread,
May 6, 2011, 4:49:30 PM5/6/11
to
I have just spent (wasted) an hour trying to find a bug in code, which
is somewhat longer than this, but the essence is in this contrived example:

module mymod
implicit none
contains
!---------------------------------------------------------
subroutine mysub(param, result)
real, intent(in) :: param(3)
real, intent(out) :: result
print *,'param=', param
result = 0.0
end subroutine mysub
!---------------------------------------------------------
subroutine minim(param, subr, result)
real, intent(in) :: param(:)
interface
subroutine subr(p, r)
real, intent(in) :: p(:)
real, intent(out) :: r
end subroutine subr
end interface
real, intent(out):: result
!
call subr(param, result)
end subroutine minim
end module mymod
!----------------------------------------------------------

program main
use mymod
implicit none
real :: param(3) = [1.0, 2.0, 3.0], result
call minim(param, mysub, result)
end program main


This was in a minimisation routine and the only symptom was that the
results were completely wrong. In the example above the print statement
might be expected to print the values 1. 2. 3. but it didn't with the
code as shown. Perhaps in an example as simple as this I might have
spotted the mis-match right away, but in the real case it took me an
hour. I tried it with both gfortran and g95 with all possible
compile-time and run-time diagnostics enabled, but neither of them came
up with as much as a warning.

No doubt you will have spotted by now the error in the 5th line, where
param(3) should have been param(:). Normally it might not matter having
an explicit declaration where an assumed shape array is actually
required, but here it does. It seems to me that this is an unfortunate
pitfall lying in wait for the unwary programmer. I'll know another time.


--
Clive Page

Colin Watters

unread,
May 6, 2011, 5:18:07 PM5/6/11
to
"Clive Page" <use...@page2.eu> wrote in message
news:92j56q...@mid.individual.net...

Yes. IMO the culprit here is the lack of a way for the compiler to check
the definition supplied with the INTERFACE block, against the actual
definition of the routine (which starts at line 5). Hence I try all ways to
avoid using INTERFACE. Im many cases putting the routine in a module and
USEing it is sufficient, but in examples such as yours this is not possible
I think.

CVF 6.6a allowed a routine to declare an "interface to itself". Thus you
could put the interface definition (or a whole slew of them) in an include
file, and reference it from all the routines so described (as well as the
ones calling them). Any discrepancies gave a compile-time error, which was
of course the desired effect. Alas interface to one's self is illegal per
the standard, so IVF didn't provide it as a backwards-compatability
feature.

Would procedure pointers help here I wonder?

--
Qolin

Email: my qname at domain dot com
Domain: qomputing


mecej4

unread,
May 6, 2011, 7:16:10 PM5/6/11
to
I think an abstract interface is just what is needed, since the missing
interface is for a procedure argument.

-- mecej4

James Van Buskirk

unread,
May 7, 2011, 12:08:29 AM5/7/11
to
"Clive Page" <use...@page2.eu> wrote in message
news:92j56q...@mid.individual.net...

> I tried it with both gfortran and g95 with all possible

> compile-time and run-time diagnostics enabled, but neither of them came up
> with as much as a warning.

One can try checking in the dummy procedure or in the procedure
with the dummy procedure as argument, but neither works. Seems
like something gfortran should have caught. The warning it gives
is fine and was discussed in a previous thread but had nothing to
do with the problem in the code.

C:\gfortran\clf\chkparam>type chkparam.f90


module mymod
implicit none
contains
!---------------------------------------------------------
subroutine mysub(param, result)
real, intent(in) :: param(3)
real, intent(out) :: result
print *,'param=', param
result = 0.0

if(.FALSE.) call minim(param,mysub,result)


end subroutine mysub
!---------------------------------------------------------
subroutine minim(param, subr, result)
real, intent(in) :: param(:)
interface
subroutine subr(p, r)
real, intent(in) :: p(:)
real, intent(out) :: r
end subroutine subr
end interface
real, intent(out):: result

procedure(mysub),pointer :: chkproc
!
call subr(param, result)
if(.FALSE.) chkproc=>subr


end subroutine minim
end module mymod
!----------------------------------------------------------

program main
use mymod
implicit none
real :: param(3) = [1.0, 2.0, 3.0], result
call minim(param, mysub, result)
end program main

C:\gfortran\clf\chkparam>gfortran chkparam.f90 -ochkparam
chkparam.f90:10.29:

if(.FALSE.) call minim(param,mysub,result)
1
Warning: Non-RECURSIVE procedure 'mysub' at (1) is possibly calling itself
recur
sively. Declare it RECURSIVE or use -frecursive

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


Ian

unread,
May 7, 2011, 3:47:31 PM5/7/11
to
The Polyhedron site has a lot of information about the capabilities
of Fortran compilers.

This page

http://www.polyhedron.com/pb05-win32-diagnose0html

has details about the diagnostic capability of the windows compilers.

here is the output from the Nag compiler with your skeleton
program.

d:\document\fortran\newbook\examples\temp>nagfor cp.f90
NAG Fortran Compiler: Release 5.2(722)
Evaluation trial version of NAG Fortran Compiler Release 5.2(722)
Extension: cp.f90, line 31: Brackets [] used for array constructor
detected at 3.0@]
Error: cp.f90, line 32: Dummy proc SUBR arg 1 is assumed-shape, actual
proc MYSU
B arg is not
Error: cp.f90, line 32: Incompatible procedure argument for SUBR (no.
2) of MINI
M
[NAG Fortran Compiler error termination, 2 errors, 1 warning]

with default compilation options.

We regard their pricing and annual maintenance as
very good value.

Jane Sleightholme and I have taught using their
compilers since the availability of the first
Fortran 90 compiler, which was of course from Nag.

We recommend it very highly.

Ian Chivers

Clive Page

unread,
May 7, 2011, 4:20:00 PM5/7/11
to
On 07/05/2011 20:47, Ian wrote:

> Error: cp.f90, line 32: Incompatible procedure argument for SUBR (no.
> 2) of MINI
> M
> [NAG Fortran Compiler error termination, 2 errors, 1 warning]

Ian, thanks for pointing that out - I do have access to the NAG compiler
at work, but hadn't got around to trying it on this case. It does, as
you say, have good diagnostics, but my experience is that generally
every compiler seems to be able to diagnose some problem that the others
miss.


--
Clive Page

dpb

unread,
May 7, 2011, 4:48:04 PM5/7/11
to
On 5/6/2011 3:49 PM, Clive Page wrote:
> I have just spent (wasted) an hour trying to find a bug in code, which
...

CVF 6.6a does the following...

C:\Temp> df CLIVE.F90
CLIVE.F90
CLIVE.F90(30) : Error: The characteristics of dummy argument 1 of the
associated actual procedure differ from the characteristics of dummy
argument 1 of the dummy procedure. (12.2) [MYSUB]
call minim(param, mysub, result)
--------------------^

I'd think that pretty good indication IVF would find it also...

--

Gary L. Scott

unread,
May 7, 2011, 5:11:01 PM5/7/11
to
well maybe...but there's been fairly massive changes from CVF, like the
entire back end. I have a hard time believing that the old back end was
poorly designed, not sure why they needed to marry intel with cvf like
they did ($$$), but i guess there were good reasons.

Tim Prince

unread,
May 7, 2011, 6:40:28 PM5/7/11
to

ifort relies on the gen-interfaces option to find this sort of thing.
The option is on by default in Visual Studio but off by default on
Windows command line and linux. CVF didn't have linux support, and
generally performed the argument checking only within a single source file.
--
Tim Prince

Arjen Markus

unread,
May 9, 2011, 3:29:48 AM5/9/11
to
> Tim Prince- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -

Interesting, but if I use the command-line interface, how do I turn
this
feature on? I have experimented with -gen-interfaces and -
warn:interfaces
but I did not see any warnings (nor the typical extra files).

Regards,

Arjen

mecej4

unread,
May 9, 2011, 8:08:51 AM5/9/11
to

I don't think that such an approach will work, because there is no
procedure with the actual name SUBR. Rather, SUBR is a dummy argument,
for which MYSUB is a suitable value. What the compiler has to do is to
match the declared interface to SUBR with the actual interface to MYSUB.

The ABSTRACT INTERFACE feature of Fortran 2003 is what is probably
needed here.

-- mecej4

Arjen Markus

unread,
May 9, 2011, 8:50:38 AM5/9/11
to
> -- mecej4- Tekst uit oorspronkelijk bericht niet weergeven -

>
> - Tekst uit oorspronkelijk bericht weergeven -

Hm, you are probalby right about that, but I did not even see any
indication
of generated interfaces, whereas if I do use Visual Studio, I have
seen such
files appear. So that is why I wondered about the right invocation.

Regards,

Arjen

Ian Harvey

unread,
May 9, 2011, 7:50:52 PM5/9/11
to
On 8/05/2011 8:40 AM, Tim Prince wrote:
...

> ifort relies on the gen-interfaces option to find this sort of thing.
...

I think ifort could do better here. At the point of the call The
interface for the actual argument is explicit and the "interface for the
dummy argument" (its characteristics?) is also "explicit". There
shouldn't be a need for the /warn:interfaces type of check (not that
/warn:interface results in a warning here with 12.0.3).

Steve Lionel

unread,
May 10, 2011, 9:52:49 AM5/10/11
to
On 5/9/2011 7:50 PM, Ian Harvey wrote:
> I think ifort could do better here. At the point of the call The
> interface for the actual argument is explicit and the "interface for the
> dummy argument" (its characteristics?) is also "explicit". There
> shouldn't be a need for the /warn:interfaces type of check (not that
> /warn:interface results in a warning here with 12.0.3).

I agree and have filed a bug report on that.

--
Steve Lionel
Developer Products Division
Intel Corporation
Merrimack, NH

For email address, replace "invalid" with "com"

User communities for Intel Software Development Products
http://software.intel.com/en-us/forums/
Intel Software Development Products Support
http://software.intel.com/sites/support/
My Fortran blog
http://www.intel.com/software/drfortran

Refer to http://software.intel.com/en-us/articles/optimization-notice
for more information regarding performance and optimization choices in
Intel software products.

Daniel H

unread,
May 15, 2011, 5:14:23 AM5/15/11
to
On 05/09/2011 02:08 PM, mecej4 wrote:
(snip)

> The ABSTRACT INTERFACE feature of Fortran 2003 is what is probably
> needed here.
>
> -- mecej4

Could you give an example of what that would look like here?

Thanks

Daniel

mecej4

unread,
May 15, 2011, 11:45:28 AM5/15/11
to
I have an example that is fairly close to the one given in the original
post of this thread. It integrates two example functions using Simpson's
rule. One of the candidate functions has an error in the argument list,
and many compilers pick up that error at compile time (with compiler
options as needed).

For example, IFort 12.0.4 says:

tsimp2.f90(60): error #7061: The characteristics of dummy


argument 1 of the associated actual procedure differ
from the characteristics of dummy argument 1 of the dummy

procedure. (12.2) [SQR]
write(*,10)'sqr',simp(a,b,h,sqr)
------------------------------^
compilation aborted for tsimp2.f90 (code 1)
__________________________________________________
module funmod
abstract interface ! template for integrand function
function fn(x) result(y)
implicit none
real, intent(in) :: x
real :: y
end function fn
end interface
end module funmod

module simpmod
contains
function simp(a,b,h,fun) result(fi) ! integrate fun(x) a-step_h-b
use funmod ! contains abstract interface
implicit none
procedure(fn) :: fun ! specifies interface to fun(x)
real, intent(in):: a,b,h
real :: fi,x,p
integer i,n

n=nint((b-a)/h)
fi=fun(a)+fun(b)
p=4.0
do i=2,n
x=a+(i-1)*h
fi=fi+p*fun(x)
p=6.0-p
end do
fi=fi*(b-a)/(3.0*n)
return

end function simp
end module simpmod

module functions
contains
real function cub(x)
implicit none
real, intent(in) :: x
cub = x*x*x
return
end function cub

real function sqr(x)
implicit none
integer, intent(in) :: x ! error here; should have been REAL
sqr = x*x
return
end function sqr

end module functions

program tsimp
use functions ! integrand functions cub and sqr
use simpmod ! Simpson integration routine
implicit none
real :: a=1.0,b=2.0,h=0.05

write(*,10)'cub',simp(a,b,h,cub)
write(*,10)'sqr',simp(a,b,h,sqr)

10 format(1x,A3,2x,F10.4)
end program tsimp
_________________________________________________________________________

0 new messages