Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Multiline support in the result of a Preprocess Definition

ScottBoyce
Beginner
471 Views

I have a program that has the following fixed formatted code appearing in most of the subroutines.

[fortran]      CHARACTER(5),PARAMETER,DIMENSION(6)::KEYWORDLIST=\

     + ['ABS','EXP','LOG','L10','NEG','SQRT'] 

[/fortran]

Since this keyword list is likely to grow over time, I would like to use a macro at the beginning of the source file to have the keyword list be located in one spot and be replicated in the code (this is a shorten version).

[fortran]#define   KEYPARAM   CHARACTER(5),PARAMETER,DIMENSION(4)::KEYWORDLIST=

     + ['ABS','EXP','LOG','SQRT'] 

[/fortran]

The main problem is that I am not able to capture the multiple lines and it is too long to fit on one line.

I can not use the #include and have an extra file, nor compile with extended column support flag. 

Making it a global variable is possible, but I was concerned that it would result in a speed penalty and not be available in the ELEMENTAL/PURE subroutines. This array is used in all the subroutines for matching the keywords in loops and flag checks such as:

[fortran]       LOGICAL:: KEY

       KEY=ANY(WORD==KEYWORDLIST)

!or

       FOUND=0

       DO I=1, NLIST

         DO J=1, NKEY

            IF( INDEX( LIST(I),TRIM(KEYWORDLIST(J)) ) >0 ) THEN

               FOUND(I)=J

               EXIT

            END IF

         END DO

       END DO

[/fortran]

 

Any advice on this would be greatly appreciated.

0 Kudos
6 Replies
Michael_Roberts
New Contributor I
471 Views

Hi Scott,

Maybe I've misunderstood, but why not put this in a new free form module and USE it in the subroutines where you require it? 

Personally I would also include any lookup functions relating to this list in the module.

Others here may be able to comment on speed - but my advice is always go for clear coding first and worry about speed later. 

Cheers,

Michael

0 Kudos
John4
Valued Contributor I
471 Views

I second the advice of using modules instead.

Since KEYWORDLIST is a parameter, it will not conflict with any of the rules for PURE/ELEMENTAL procedures, as long as it's either declared in the same module or USE-associated.

The PARAMETER statement/attribute sort of serves the same purpose as a C-related #define, so the compiler will likely replace every occurrence of "KEYWORDLIST" with the actual array, during compilation.

The occurrence of "KEYWORDLIST(J)" might be treated the same way as a variable array, but that's just an advantage PARAMETER has over #define.  In any case, since your #define is simply allowing you to re-declare the same array everywhere, it won't give you any speed improvement.

The use of modules is not tied to the free source form files, so If you're more comfortable using fixed form, you can create them there as well.

 

0 Kudos
FortranFan
Honored Contributor III
471 Views

Also, note macros are not part of the Fortran standard.  Hence your code will become tied to a particular set of preprocessor tool(s) and/or compiler(s).

PARAMETERs, preferably in some module, is indeed the way to go.

0 Kudos
ScottBoyce
Beginner
471 Views

Michael Roberts wrote:

Personally I would also include any lookup functions relating to this list in the module.

Others here may be able to comment on speed - but my advice is always go for clear coding first and worry about speed later. 

Cheers,

Michael

 

Thanks Michael, but right now I have all the subroutines within a MODULE that is declared private and one of the subroutines public (the driver routine). Unfortunately I am limited with fixed format, free format is allowed where I work, but the 77 column limit is still enforced.

 

I will just move it into a module, the software is compiled with intel fortran, hopefully the compiler will just move the parameter straight into the routines.

0 Kudos
jimdempseyatthecove
Honored Contributor III
471 Views

While I would prefer module, try this:

#define   KEYPARAM   CHARACTER(5),PARAMETER,DIMENSION(4)::KEYWORDLIST=
#define   KEYPARAM1 ['ABS','EXP','LOG','SQRT'
#define   KEYPARAM2 ,'SIN','COS',...
...
#define   KEYPARMn  ...]
--------------------
SUBROUTINE FOO(...)
       IMPLICIT NONE
       KEYPARM
      +KEYPARM1
      +KEYPARM2
      +...
      +KEYPARMn
       INTEGER I
       REAL X
...

Note, you can #define more KEYPARM's than necessary and then fill them in as you go. Having a blank KEYPARM is benign.

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
471 Views

PARAMETER constants are used exactly as regular constants are - they are compile-time and impart no performance penalty at all.

0 Kudos
Reply