Reputation: 105
I'm trying to define a user defined type that one of its elements depends on another. This is a test code that summarises the way I tried;
module def
type vector
integer, parameter :: long
real,dimension(1:long) :: vec
end type vector
end module def
program main
use def
implicit none
type(vector) :: y
y%long = 2
y%vec = (/1.0d0, 2.0d0/)
print*, y
end program main
But it seems that it can't be done in this way, because when I compile it in gfortran
, I have the following error:
integer, parameter :: long
1
Error: Attribute at (1) is not allowed in a TYPE definition
testmodule.f03:4:17:
How should this be done?
Upvotes: 0
Views: 80
Reputation: 8576
How should this be done?
In fact, there is a pretty direct response to this question: parameterized derived type.
@HighPerformanceMark is right in saying that today (2019), despite this feature having been presented in a standard 16 years ago, it was barely and lately covered by compilers.
Although, and in fact this is the reason I decided to write this answer despite some existing questions about this matter, I want leave aside the controversy around this feature and present a sharp, ultimate suggestion: USE IT.
There are at least 5 major compilers that implemented this feature today (Cray, GNU, IBM, Intel, PGI). Most of them still have bugs, but they need to be used and, therefore, tested. Then, when/if you find a bug, please report to the vendor. Only this way this feature will break the stigma created over it and become popular.
I know we all have serious business to do and don't have time to spend with "fancy new untested stuff" and want proven, efficient, mathematically sensible solutions. That is why we chose Fortran, after all. I wouldn't had recommended it for this people (us) a few years ago, but now most implementations reached a level of usability that worths the bet, and the usage is the only way to trim the rough edges.
Parameterized derived types translate, intuitively, the real problem you described. It provides an automatic (and elegant) way to model the domain of the type, considering math and programming aspects at once. The correct syntax for your program is:
module def
type vector(long)
integer, len :: long
real, dimension(long) :: vec
end type vector
end module def
program main
use def
implicit none
type(vector(2)) :: y
y%vec = [1.0, 2.0]
print*, y
end program main
You can find more information about it here and also all over the internet, or in you favorite Modern Fortran book.
Upvotes: 4