Fortran [FORTRAN]Compiler if statements

  • Thread starter Thread starter Matterwave
  • Start date Start date
Click For Summary
The discussion focuses on understanding preprocessor directives in code, particularly in the context of using the GNU Fortran compiler. Participants clarify that directives like #ifdef and #define are used to conditionally compile code based on whether certain macros, such as mpi or newerrtst, are defined. The compiler recognizes these definitions through command-line switches, specifically using the -D option. Users are advised to check the makefile for any definitions related to these macros, as they may not be explicitly stated in the main code. The conversation highlights the importance of understanding how preprocessor directives function and how they can affect code execution, especially when testing different configurations. The need to explore included makefiles for macro definitions is emphasized, as it may reveal how the code is being compiled and which directives are active.
Matterwave
Science Advisor
Homework Helper
Gold Member
Messages
3,971
Reaction score
329
Hi guys, I'm not really sure what these are called, so I just made a title to the best of my knowledge. I have some questions on some if-statements that I see in some code I'm working with. I will see if-statements like this:

Code:
#ifdef mpi
...
#endif

I know that this tells the compiler that if multiple processors are being used, then use the code in between. What I don't know (and can't recall) is, how does the code know when mpi is defined or not? Where do you put in the information to tell the compiler this? It's not in the main line of code I'm reading. I also see a statement in my code:

Code:
#ifdef newerrtst
...
#endif

I'm guessing this is a custom-made test...so...where can I tell if newerrtst is defined?

What are these if-statements even called? o_O
 
Technology news on Phys.org
Matterwave said:
how does the code know when mpi is defined or not?

If you just want to be able to test whether the symbol "exists" or not:

Code:
#define mpi

You can also give it a value, which the compiler substitutes for the symbol wherever it appears in your code:

Code:
#define mpi m*pi

in which case a statement like

Code:
      result = x * mpi

becomes

Code:
      result = x * m*pi
 
Matterwave said:
What I don't know (and can't recall) is, how does the code know when mpi is defined or not? Where do you put in the information to tell the compiler this?
I don't remember whether you're using the GNU Fortran compiler. If so, you can use a switch on the command line to define values for macro names when you invoke the compiler.
From http://gcc.gnu.org/onlinedocs/gfortran/Preprocessing-Options.html#Preprocessing-Options:
-Dname=definition
The contents of definition are tokenized and processed as if they appeared during translation phase three in a '#define' directive. In particular, the definition will be truncated by embedded newline characters.
If you are invoking the preprocessor from a shell or shell-like program you may need to use the shell's quoting syntax to protect characters such as spaces that have a meaning in the shell syntax.
If you wish to define a function-like macro on the command line, write its argument list with surrounding parentheses before the equals sign (if any). Parentheses are meaningful to most shells, so you will need to quote the option. With sh and csh, -D'name(args...)=definition' works.
-D and -U options are processed in the order they are given on the command line. All -imacros file and -include file options are processed after all -D and -U options.
 
Mark44 said:
I don't remember whether you're using the GNU Fortran compiler. If so, you can use a switch on the command line to define values for macro names when you invoke the compiler.
From http://gcc.gnu.org/onlinedocs/gfortran/Preprocessing-Options.html#Preprocessing-Options:

Does that mean that the makefile should have such information in it? I am using the GNU Fortran compiler, yes. What I want to test is to turn off "newerrtest" and see what the code does, but I don't know how to do that lol.

EDIT: I checked the makefile and it doesn't seem to have any mention of these variables...hmmm
 
Last edited:
Matterwave said:
I'm not really sure what these are called

They're called "preprocessor directives". A Google search on this will turn up lots of information. You'll see lots of references to the "C preprocessor" but the GNU C++ and Fortran compilers also use it.
 
jtbell said:
They're called "preprocessor directives". A Google search on this will turn up lots of information. You'll see lots of references to the "C preprocessor" but the GNU C++ and Fortran compilers also use it.

Ok, thanks, I will google it! :D
 
To add to the other good answers, I'll point out that the C preprocessor is called by most Fortran compilers if the filename has an uppercase F in the extension: .F, .F90, .F95, etc.

In your case, since you are simply checking if a variable is defined, you don't need to specify a 'definition' (see post #3). For example, to compile with mpi:
Code:
gfortran -c -Dmpi mycode.F90
To compile without mpi:
Code:
gfortran -c mycode.F90
 
DrClaude said:
To add to the other good answers, I'll point out that the C preprocessor is called by most Fortran compilers if the filename has an uppercase F in the extension: .F, .F90, .F95, etc.

In your case, since you are simply checking if a variable is defined, you don't need to specify a 'definition' (see post #3). For example, to compile with mpi:
Code:
gfortran -c -Dmpi mycode.F90
To compile without mpi:
Code:
gfortran -c mycode.F90

Thanks for this information, this was clear, but my code is all built and compiled using a makefile (as I think you probably know haha). I checked the makefile and could not see any declarations like -Dmpi or -Dnewerrtest or anything like that, so it would seem to suggest the code should be compiled without any of these preprocessor directives defined? The weird thing though is that it seems to be running all the code that are sandwiched between #ifdef newerrtest/#endif directives...I checked this by modifying some code inside these tags and the code ran considerably differently!
 
Matterwave said:
Thanks for this information, this was clear, but my code is all built and compiled using a makefile (as I think you probably know haha). I checked the makefile and could not see any declarations like -Dmpi or -Dnewerrtest or anything like that, so it would seem to suggest the code should be compiled without any of these preprocessor directives defined? The weird thing though is that it seems to be running all the code that are sandwiched between #ifdef newerrtest/#endif directives...I checked this by modifying some code inside these tags and the code ran considerably differently!
Looking back at your Makefile, I think you should check the file makefile.gfortran, which is "included" in the Makefile, for the values of FFLAGS and FOPT.
 
  • #10
DrClaude said:
Looking back at your Makefile, I think you should check the file makefile.gfortran, which is "included" in the Makefile, for the values of FFLAGS and FOPT.

Oh great! Will do thanks! :D
 
  • #11
The makefile in your thread about makefiles has this:
Code:
MACH =  gfortran
include makefile.$(MACH)
.
.
.
keep_clocks.o  : keep_clocks.F90 params.o
   $(F90) $(FFLAGS) $(FOPT) -c keep_clocks.F90
See if there's a file named makefile.gfortran. I'm guessing it has definitions for the various macros used in your makefile. The last line above apparently calls the Fortran 90 compiler - $(F90) with a set of command line flags - $(FFLAGS) and options - $(FOPT).
 
  • #12
This is makefile.gofortran:
Code:
##-----------------------------------------
##  pc makefile stuff
###-----------------------------------------
.SUFFIXES:
.SUFFIXES: .F90 $(SUFFIXES)
DEFINES +=
######-----------------------------------------
F90 = gfortran
FCOMPPAR= gfortran
F77 = gfortran
F77COMP = gfortran
FTRANS =
F90PAR = gfortran
FFLAGS = $(DEFINES)
LDFLGS = $(FFLAGS)
#include profiling
FOPT = -O3
FNOOPT =
FLIBS =

I'm not seeing anything like -Dmpi or -Dnewerrtest though... o_O

EDIT: Ahh... I took a closer look at the code I edited. Perhaps newerrtest is not implemented after all since I think I might have edited a piece of code in an #else part...

But thanks for the information guys!
 

Similar threads

  • · Replies 8 ·
Replies
8
Views
4K
  • · Replies 27 ·
Replies
27
Views
6K
Replies
6
Views
3K
Replies
59
Views
8K
  • · Replies 6 ·
Replies
6
Views
12K
  • · Replies 13 ·
Replies
13
Views
2K
  • · Replies 13 ·
Replies
13
Views
1K
  • · Replies 20 ·
Replies
20
Views
3K
  • · Replies 37 ·
2
Replies
37
Views
4K
  • · Replies 2 ·
Replies
2
Views
3K