- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello all, I have a general question regarding Fortran syntax (not this forum?). I have a series of include files that set up memory structures, and those include files may also chain-include other files.....in this case, some "parameter definition" files. For example:
INCLUDE 'MEMORY_PARMS.TEXT' STRUCTURE /SOME_ARRAY/ INTEGER*4 ID REAL*4 SOMEVARX(COUNT) REAL*4 SOMEVARY(COUNT) END STRUCTURE
...and 'MEMORY_PARMS.TEXT' contains the following:
!DIR$ IF .NOT. DEFINED(_MEMORY_PARMS_TEXT_) !DIR$ DEFINE _MEMORY_PARMS_TEXT_ INTEGER*4 COUNT PARAMETER (COUNT = 1000) !DIR$ ENDIF
This is just a small example -- we are trying to use a single "parameters" file to tune the scalability of our program, rather than having to go through dozens of source files to change hundreds of array sizes, etc. This works great for single-routine files, but the problem is when someone codes a file that has more than one subroutine definition inside.....the first routine that includes the common block chain-includes the MEMORY_PARMS.TEXT file, defines the COUNT variable, and works. The second routine, however, includes the same common block, but the preprocessor dutifully doesn't redefine the COUNT variable (since _MEMORY_PARMS_TEXT_ was defined by the first pass through while compiling the first routine), and the compilation fails. The goal of the preprocessor directives was to avoid variable redefinition errors if multiple INCLUDEd files brought in the same params file in the same routine, however we didn't consider the case of how to "reset" this behavior in the case of a subsequent subroutine in the same compilation unit. I was hoping there would be a preprocessor macro called something like __MODULE__ or __ROUTINE__ which some fancy fpp DEFINE logic can compare-test and then set if it's different, but alas, there appears to be no such macro.
Anyone have any thoughts?
Thanks.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Perhaps I'm missing something, but I'd think that using modules and definitions in the modules would be a preferable approach. I'll note that you're using a compiler-specific preprocessor syntax rather than the more common cpp-style, but that's just an observation and not relevant to your problem.
If you're writing new code, I'd very strongly recommend making use of the language features designed for information sharing. (And perhaps module variables rather than COMMON blocks, though I'll comment that both make it difficult to parallelize your application.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Consider using the FPP preprocessor (and preprocessor directives). These are the C style preprocessing directives.
Your attempt to use the Compiler Directive !DIR$ as if it were equivalent to the C preprocessor is giving you problems. Using the FPP (C-like) will provide the same functionality.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When I change the PARAMETER entries to:
#define COUNT 1000
...and compile with "ifort -fpp myfile.for", I receive a "warning #5117: Bad # preprocessor line", and a number of errors I interpret to mean the preprocessor definitions are not being honored.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can you show a sample source, the command line and output? The error you describe is what I would expect to see if fpp was not enabled.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sure. Rename "defines.f" to "defines.text", which the uploader won't allow.
I used "ifort -fpp test.for". Output:
$ ifort -fpp test.for ./defines.text(1): warning #5117: Bad # preprocessor line #ifndef __defines_inc__ -^ ./defines.text(2): warning #5117: Bad # preprocessor line #define __defines_inc__ -^ ./defines.text(4): warning #5117: Bad # preprocessor line #define COUNT 1000 -^ ./defines.text(6): warning #5117: Bad # preprocessor line #endif -^ test.for(10): error #6219: A specification expression object must be a dummy argument, a COMMON block object, or an object accessible through host or use association [COUNT] REAL*4 TEST2(COUNT) ------------------------------^ test.for(10): error #6591: An automatic object is invalid in a main program. [TEST2] REAL*4 TEST2(COUNT) ------------------------^ test.for(11): error #6591: An automatic object is invalid in a main program. [TEST3] INTEGER*4 TEST3(COUNT), I ------------------------^ compilation aborted for test.for (code 1)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have taken the risk of replying without looking at your attached files. The cpp # syntax does not mix well with Fortran code. It firstly requires you to throw out all instances of INCLUDE and replace them with #include because the # compiler directives are applied before the Fortran processor makes a pass through the file, so by the time a chunk of code is inserted with INCLUDE, the C preprocessor isn't available to figure out the # directives in the INCLUDEd chunk any more.
Instead of changing everything to C, it seems to me to make much more sense to use modules to set values globally. That way everything is in transportable Fortran and you don't have to keep second-guessing the C preprocessor to get your code right.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can still use the Fortran INCLUDE *** as long as they do not contain any FPP directives nor contain FPP declared macros.
You are correct in that the easiest way is to use the FPP "#include ..." in these circumstances.
For the OP's tuning requirement I agree with Steve's recommendation of placing these into a module file, then insert USE ... in the appropriate places.
Jim Dempsey

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