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

generic interface question

3 views
Skip to first unread message

fj

unread,
Aug 28, 2007, 5:39:30 PM8/28/07
to
I would like to create a generic interface but the routines performing
the work are not located within the same module.

I tried a syntax like the following (and several variants) :

MODULE a
USE b, ONLY : foo1
INTERFACE foo
MODULE procedure foo1,foo2,foo3
END INTERFACE
CONTAINS
SUBROUTINE foo2(...)
...
SUBROUTINE foo3(...)
...
END MODULE

Of course, foo1 , foo2 and foo3 have not the same signature. But the
compiler complains because it does not want to change the host
association of "foo1".

I tried to find examples on the net without success. Is it possible ?
If yes what is the correct syntax ?

Thank you in advance

Richard Maine

unread,
Aug 28, 2007, 6:05:30 PM8/28/07
to
fj <franco...@irsn.fr> wrote:

> I would like to create a generic interface but the routines performing
> the work are not located within the same module.
>
> I tried a syntax like the following (and several variants) :
>
> MODULE a
> USE b, ONLY : foo1
> INTERFACE foo
> MODULE procedure foo1,foo2,foo3
> END INTERFACE
> CONTAINS
> SUBROUTINE foo2(...)
> ...
> SUBROUTINE foo3(...)
> ...
> END MODULE
>
> Of course, foo1 , foo2 and foo3 have not the same signature. But the
> compiler complains because it does not want to change the host
> association of "foo1".

1. That looks fine to me.

2. This has absolutely zero to do with host association. In fact, the
phrase "change the host association" makes no sense in any context I can
think of. Is that actually what the compiler says, or is that your
words?

I'm tempted to suggest that it sounds like a compiler bug, but there is
too much missing here for me to say that. I'd need to see the exact
code. That means the code itself rather than explanations about it. No
ellipses. Specifically, I'd want to verify for myself that the
signatures of the specific procedures are all different; there are
tricky parts to the rules. I'd also want it complete enough that I could
try compilation with a different compiler. I'd also need to see the
exact error message.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain

fj

unread,
Aug 28, 2007, 6:33:33 PM8/28/07
to
On 29 août, 00:05, nos...@see.signature (Richard Maine) wrote:

Unfortunately, the modules are very large. I will try to build up a
smaller test case which reproduces the trouble. The exact first
message I get from the compiler is :

[lcoul@b04p0004 odessa-2003]$ g95 -c odessa_base_main.f90
In file odessa_base_main.f90:17

MODULE PROCEDURE
odessa_base_initialize,odinit,odinitodig,odinitodrg,odin
1
Error: Cannot change attributes of USE-associated symbol
'odessa_base_initialize' at (1)

The 20 first lines of the module are :

MODULE odessa_base_main

USE odessa_base_types
USE odessa_c

IMPLICIT NONE

PRIVATE

PUBLIC
odinit,odput,odinsert,odget,odgetptr,odgetcopy,odgetptrfamily,odgetcopyfamily,&

oddelete,oddeleteroot,odremove,odcard,odtype,odname,odhashname,odhashval,&
odgetfamily,odprotect,odnullify

PUBLIC ASSIGNMENT(=)

INTERFACE odinit
MODULE PROCEDURE
odessa_base_initialize,odinit,odinitodig,odinitodrg,odinitodig1,odinitodrg1,&

odinitodt,odinitodt2,odinitodi1,odinitodr1,odinitodc1,odinitodi2,&

odinitodr2,odinitodbase0,odinitodrg0,odinitodig0,odinitodt0,&

odinitodi10,odinitodr10,odinitodc10,odinitodi20,odinitodr20
END INTERFACE

And the routine odessa_base_initialize is defined in the module
"odessa_c" :

MODULE odessa_c

! interface module to call ODESSA C routines by Fortran.(2003)

USE iso_c_binding

...

INTERFACE ! odessa_segment
SUBROUTINE odessa_segment_initialize()
BIND(C,name="odessa_segment_initialize")
END SUBROUTINE
...

Of course, after reading your message, I tried to build up a very
simple test case ... which does not reproduce the trouble as usual !

MODULE a
CONTAINS
SUBROUTINE foo1(a)
INTEGER ::a
END SUBROUTINE
END MODULE
MODULE b
USE a,ONLY : foo1


INTERFACE foo
MODULE procedure foo1,foo2,foo3
END INTERFACE
CONTAINS

SUBROUTINE foo2(a)
DOUBLE PRECISION ::a
END SUBROUTINE
SUBROUTINE foo3(a)
CHARACTER ::a
END SUBROUTINE
END MODULE

[lcoul@b04p0004 test]$ g95 -c test2.f90
[lcoul@b04p0004 test]$

fj

unread,
Aug 28, 2007, 6:47:36 PM8/28/07
to
Oups !

I did not give you the correct part of the module odessa_c but the
routine odessa_base_initialize is defined exactly like
odessa_segment_initialize : an association to a C routine using the
F2003 syntax BIND(C,name="...")

Perhaps should I contact Andy Vaught directly ...

fj

unread,
Aug 28, 2007, 6:53:11 PM8/28/07
to
Yes I have now a small test case which reproduces the trouble :

MODULE a
USE iso_c_binding
INTERFACE
SUBROUTINE foo1(a) BIND(C,name="a_c_routine")
IMPORT C_INT
INTEGER(C_INT) ::a
END SUBROUTINE
END INTERFACE


END MODULE
MODULE b
USE a,ONLY : foo1
INTERFACE foo
MODULE procedure foo1,foo2,foo3
END INTERFACE
CONTAINS
SUBROUTINE foo2(a)
DOUBLE PRECISION ::a
END SUBROUTINE
SUBROUTINE foo3(a)
CHARACTER ::a
END SUBROUTINE
END MODULE

[lcoul@b04p0004 test]$ g95 -c test2.f90

In file test2.f90:13

MODULE procedure foo1,foo2,foo3
1
Error: Cannot change attributes of USE-associated symbol 'foo1' at (1)

Richard Maine

unread,
Aug 28, 2007, 9:17:41 PM8/28/07
to
fj <franco...@irsn.fr> wrote:

Ah. Now that I think I can help with.

The error message is a little confusing (though not so much so as the
paraphrasing that talked about changing host association), but I think
the critical bit here is that foo1 is *NOT* a module procedure.

Yes, I know that you accessed it via a USE statement, but that doesn't
make it a module procedure. It is an external procedure whose interface
happens to be defined in a module.

So I don't think this is a compiler bug, other than perhaps insomuch as
the error message could be better.

There is a bit of "silliness" in the f95 module procedure statement.
Mostly the whole business about restricting it to module procedures is
what seems silly to me. I don't think that restriction was well thought
out. It isn't as though the restriction achieves anything useful. I
think the writers just overlooked the fact that it could be useful for
procedures other than module ones. There are several things that are
really awkward because of this restriction. (Notably, it is hard to put
a single external procedure in two different generics; I'm not even sure
there is a workaround to that one.)

The silliness was fixed in f2003. I don't recall whether Andy yet
implemented the f2003 form of this statement in g95. In f2003, you just
omit the keyword "module" and it no longer has the silly restriction.
Otherwise, if you are stuck with the f95 form, you have to use some kind
of workaround. Ones that occur to me are

1. Put the interface body for foo1 in the generic interface block in
module b (and then don't USE foo1 from module a).

2. Or put a generic interface block for foo in module a, with just foo1
as a specific. You can then extend the generic in module b.

Yes, I know these workarounds can be awkward in some cases. The f2003
fix is better.

fj

unread,
Aug 29, 2007, 7:31:07 AM8/29/07
to
On 29 août, 03:17, nos...@see.signature (Richard Maine) wrote:


Sorry for my very approximative translation of a message I did not
understand ;-)

And thank you for your useful help

FJ

0 new messages