[FORTRAN]Compiler if statements

1. Nov 4, 2014

Matterwave

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 (Text):
#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 (Text):
...
#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?

2. Nov 4, 2014

Staff: Mentor

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

Code (Text):

#define mpi

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

Code (Text):

#define mpi m*pi

in which case a statement like

Code (Text):

result = x * mpi

becomes

Code (Text):

result = x * m*pi

3. Nov 4, 2014

Staff: Mentor

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:

4. Nov 4, 2014

Matterwave

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: Nov 4, 2014
5. Nov 4, 2014

Staff: Mentor

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.

6. Nov 4, 2014

Matterwave

Ok, thanks, I will google it! :D

7. Nov 5, 2014

Staff: Mentor

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 (Text):

gfortran -c -Dmpi mycode.F90

To compile without mpi:
Code (Text):

gfortran -c mycode.F90

8. Nov 5, 2014

Matterwave

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!

9. Nov 5, 2014

Staff: Mentor

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. Nov 5, 2014

Matterwave

Oh great! Will do thanks! :D

11. Nov 5, 2014

Staff: Mentor

Code (Text):

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. Nov 5, 2014 Matterwave This is makefile.gofortran: Code (Text): $-----------------------------------------$ 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...

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!