- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We are using an old FORTRAN program which I am trying to set up to date.
One of the main change is converting COMMONs to MODULEs.
But most of the COMMONs include STRUCTUREs which are in an INCLUDE file :
File DECLAR.f90
structure /drap/
integer*4 art
integer*4 col
end structure
Subroutine B
subroutine b
include "declar.f90"
type (drap) d1,d2
common /ddarp/ d1
d1=d2
return
end
Program A
program a
include "declar.f90"
type (drap) d1,d3
common /ddarp/ d1
call b
d3=d1
end
I did change it to :
module structure_drap
structure /drap/
integer*4 art
integer*4 col
end structure
end module structure_drap
module ddrap
use structure_drap
type (drap) d1
end module ddrap
subroutine b
use structure_drap
use ddrap
type (drap) d2
d1=d2
return
end
program a
use structure_drap
use ddrap
type (drap) d3
d3=d1
return
end
The compiler output the following error :
This type/structure name has been defined more than once. (DRAP)
Note that every module, every subroutine and the main programs are different files and I build all the subroutines a static library.
I tried to have 2 different STRUCTUREs DRAP1 and DRAP2, but then the compiler refuses d1=d2 and d3=d1.
How can I do ?
And other problem using INTERFACE : the compiler outputs and error when compiling a subroutine together with its INTERFACE. It is very complicated to turn around that + it would be a double check if the compiler could verify the compatibility of the subroutine and its INTERFACE.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am not sure how the double definition comes about, but can you change the structure to a derived type? I do not know exactly what structures do, but they are not part of any standard that I know of. Getting rid of such non-standard constructs would have priority, I'd say.
As for interfaces: if a routine is contained in a module, then the interface to that routine is automatically known. There is no need to define it separately and indeed the compiler does not like that.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello
May I suggest the following structure :
NB : You can replace type by structure/record but I don't see the benefit
module typ_drap type drap integer*4 art integer*4 col end structure end module typ_drap module com_drap use typ_drap type (drap) d1 end module com_drap subroutine b use com_drap type (drap) d2 d1=d2 return end function program a use com_drap type (drap) d3 d3=d1 return end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
module structure_drap structure /drap/ integer*4 art integer*4 col end structure type (drap) :: d1 end module structure_drap
every where you put 'use structure drap' the type drap will be available to define local variables of this type
and the global 'shared' variable d1 will be available.
Structure is non standard btw the standard way would be
type drap sequence integer(4) :: art integer(4) :: col end type drap
Sequence is only needed if you are relaying on the elements of drap being stored in the order they are defined in the code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jmloriot: In #1, you are mixing up the syntax for declaring F90+ derived type variables and the non-standard STRUCTURE variables. For the latter, the keyword to use in variable declarations is RECORD, not TYPE (...). In your main program, for example, replace
type (drap) d1,d3
by
record /drap/ d1,d3
As others have already suggested, it is best to convert the nonstandard declarations, if doing so is feasible in your existing projects. If you are writing new code, on the other hand, there is no reason to use the STRUCTURE types at all.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
app4619 wrote:
module structure_drap structure /drap/ integer*4 art integer*4 col end structure type (drap) :: d1 end module structure_drapevery where you put 'use structure drap' the type drap will be available to define local variables of this type
and the global 'shared' variable d1 will be available.
Structure is non standard btw the standard way would be
type drap sequence integer(4) :: art integer(4) :: col end type drapSequence is only needed if you are relaying on the elements of drap being stored in the order they are defined in the code.
I always separate définitions typ_xxx module from common variables definitions com_xxx module. I find this way more clear and I can use typ_xxx module in function/subroutine déclarations where I doesn't need the common variables:
function dummy(x) use typ_xxx type (xxx) x end function
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
gvautier wrote:
I always separate définitions typ_xxx module from common variables definitions com_xxx module. I find this way more clear and I can use typ_xxx module in function/subroutine déclarations where I doesn't need the common variables:
A matter of choice really, I make great use of use xxx, only: yyy where I want to use a limited number selection of things from a module.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>A matter of choice really, I make great use of use xxx, only: yyy where I want to use a limited number selection of things from a module.
Agreed, however, I prefer gvautier's position as my experience from converting large projects (100's to 1,000's of files) that the type declarations and data tend to change less frequently than the code (that which would be in the CONTAINS section of the module). Having both combined in the same module results in a large number of unnecessary compiles. The only:yyy will not inhibit the unnecessary compilation. An additional step over gvautiler's recommendation is to create an interfaces module to declare the interfaces used in the module containing the code (contains section). Interfaces of the code tends to change less frequently than the code. When I adopted this strategy it was on a P4 system where a build all would take on the order of 15 minutes. Prior to adopting this strategy, a one line change in some contains section resulted in 10+ minute recompile. After the adoption, ~10 second recompile. Note, this is most effective during conversion while not using multi-file IPO.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When updating old code, you should not have to replace structures with types. At least in IVF, the old syntax works just fine. As already mentioned, when writing new code you would be advised to use the newer syntax; or if you REALLY want to modernize the old codes you should replace it anyway.
Regarding SEQUENCE, it is not a sufficient explanation to say that it is only needed if you want to rely on the storage order of the elements. The problem is that there are places where you may be relying on it without realizing it. For example, if you want to use the "structure" (derived type) as an argument in a subroutine call, without providing an explicit interface, you will need the SEQUENCE statement. Unfortunately this is not very well documented (as described in a recent post on this forum).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Jim #8 > Valid points and and I fully understand where you are coming from. However in the case of an interfaces module I dislike that solution in principal because there is extra work in creating the interfaces and and additional opportunity to get it wrong. That scheme is a workaround for a deficiency the the Fortran module concept that creates massive build cascades in large complex projects. I concede that it is a workaround that my have to be used sometimes. I guess we will all have to wait for the SUBMODULE feature of F2008 to be implemented, which if my understanding is correct should eliminate this problem if used appropriately.
Does Dr Fortran have some when ifort might have Submodules, Is it a next 12 months thing or a further horizon?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hmm, how can I put this... You should pay attention when we announce our next beta test...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>a deficiency the the Fortran module concept that creates massive build cascades in large complex projects..
Prior to the three-way partitioning it was rather difficult to NOT have circular dependencies (while not having one humongous module with everything in it).
I am not sure if SUBMODULEs will fix this (resolution of unnecessary recompilation by segregating code from data from interfaces).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
To solve this massive rebuild cascade, I use a method that is not clean but efficient. I put the .mod files of my libraries manually in an modules directory added to the include directory list of all projects that depends of these modules. The only point is not to forget to copy the modified modules files after a change in public symbols (declarations, variables or function and subroutines).
I have'nt found a better solution.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page