4

I am trying to put newlines inside a preprocessor macro.

One reason I want this is to deallocate a number of variables, but first check to make sure they were allocated. If they're not allocated, then there should be a useful error. In this example:

$ cat main.F90 
program main
   implicit none
   integer :: n = 10
   integer, allocatable, dimension(:) :: x, y

   allocate(x(n))

#define check_deallocate(QQQ) \
   if (.not. allocated(QQQ)) then \
      write(*,*) '** Error, QQQ is not allocated' \
      error stop \
   else \
      deallocate(QQQ) \
   endif

   check_deallocate(x)
   check_deallocate(y)

end program

For this code, I get the following:

$ gfortran -E main.F90   #-E outputs the preprocessed source
...
   if (.not. allocated(x)) then       write(*,*) '** Error, x is not allocated'       error stop    else       deallocate(x)    endif
   if (.not. allocated(y)) then       write(*,*) '** Error, y is not allocated'       error stop    else       deallocate(y)    endif
...

Obviously, this is undesirable because the 132 character limit is not respected. Hence my question: what is the syntax to include a newline in the preprocessed source code?

Here are some things I have found that do not quite answer my question

  • This question was asked for C++ here, but it doesn't appear to work for fortran.

  • I do not want to define another macro (such as ___CR__) and use sed or some other utility to replace it with \n. I would like the solution to exist within 'typical' preprocessors (eg. ifort and gfortran).

If what I'm asking for is not possible, that's an answer to my question also. Also, I'm somewhat aware of the lack of standardization in fortran preprocessors, but I'm still asking for a relatively generic solution.

Ross
  • 2,130
  • 14
  • 25
  • ifort supports only a subset of the C/C++ preprocessor directives: https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-using-fpp-preprocessor-directives – Scientist Dec 13 '19 at 18:34

1 Answers1

4

It's not possible on its own, but if you're allowed to use a separated preprocess step, you could do it with the following:

SUFFIXES:
.SUFFIXES: .f90 .o

.f90.o:
    fpp -P $/n/g' > $*.ftn
    ifort -free -c $*.ftn

(untested. I found this suggestion at this link)

L. Scott Johnson
  • 4,213
  • 2
  • 17
  • 28
  • I saw that link, but I didn't understand what the `-P` argument is actually doing for fpp. Can you explain? Also, (as mentioned in the question), I am trying to *avoid* using other utilities or adding complexity, such as via a required standalone fpp call. – Ross Dec 12 '19 at 20:01
  • If you can provide a source (or even the answer stands for a while) for your first phrase, **It's not possible on its own**, that's sufficient for me. I find it somewhat surprising, though... – Ross Dec 12 '19 at 20:01
  • The linked article seems to indicate that it's not possible. That's my only source for that statement. – L. Scott Johnson Dec 12 '19 at 20:41
  • @Ross : the -P directive is there to prevent confusion, as the line numbers could be changed by the command that follows. – L. Scott Johnson Dec 16 '19 at 12:45