I have a large Fortran code which uses the Merge function in named constant (parameter) declaration. But, there is a problem in compilation.
To explain the problem, a simple code is
CHARACTER*3,PARAMETER :: Mode = 'yes' ! 'yes' or 'no'
INTEGER,PARAMETER :: L = merge(1,2, trim(Mode) .eq.'yes')
INTEGER,DIMENSION(L) :: some_array
(One changes Mode depending on the purpose. Actual code is more complex, of course.)
The points are (1) parameter 'L' is initialized depending on 'Mode' (2) parameter 'L' is used to define other arrays.
This initialization of 'L' is okay for recent compiler.
However, the cluster machine has older version (around year 2013) of Fortran compiler, which does not accept this way of initialization of 'L'.
How can I achieve the same effects in old Fortran standard?
The statements given are valid under Fortran 2003 and later, but not in Fortran 90/95.
You really want to be using a compiler which supports Fortran 2003 (and indeed much later versions) and the comments suggests ways to look for this. There is no guarantee that this is the only Fortran 2003+ parts of the code you want to compile. However, there's a history lesson available here which tells us about a workaround.
First, the obvious workaround is
integer, parameter :: L=1 ! Change to 2 if mode is 'no'
but that's not nice. (As also commented, you may make this nicer by using non-Fortran preprocessing macros.)
As has been noted elsewhere, Fortran 2003 significantly expanded on what is allowed to be used to set the value of a named constant. In both Fortran 95 and Fortran 2003 the expression for setting the value is an initialization expression. However, in Fortran 95 merge (which is an elemental function) may not be used, because in that standard elemental functions can appear in initialization expressions only if all arguments are character or integer: the mask argument is logical. Fortran 2003 removed this restriction.
You will not sensibly be able to rewrite the initialization expression under the Fortran 95 rules.
Which leads to a second workaround.
You want to use the named constant L in the array specification of some_array. However, the array specification here need only be a (constant) specification expression, not necessarily a constant like L. A Fortran 95 specification expression is looser than an initialization expression:
character(len=3), parameter :: Mode = 'yes' ! 'yes' or 'no'
integer, dimension(merge(1,2, trim(Mode).eq.'yes')) :: some_array
This isn't as nice as a named constant.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With