pgfortran: Preprocessing Error

The preprocessing phase of pgfortran mishandles the following code:

#define MACRO(fmt) write(6,fmt)
program test
  MACRO("('Hello, World!', &
  & /,'Goodbye, World.')")
end program

Although a warning is produced [PGF90-W-0225-Argument mismatch for MACRO (macro2.F90: 4)] the results of preprocessing don’t even make sense:

program test
	write(6,"('Hello, World!', &
	& /)")
end program

Thanks.

Hi thfanning,

Since Fortran doesn’t have a standard for preprocessing directives, we use a C-like method. Given this, it won’t recognize a Fortran continuation character.

  • Mat

Lack of a standard for preprocessing is certainly unfortunate. However the preprocessor is not correctly handling the quoted argument in the original example. Somehow it thinks the comma after the “/” is the argument separator. But there are several other commas before that, all of which are inside the quoted argument.

The problem appears when a combination of quotes and parentheses are present:

#define MACRO(arg1,arg2) write(6,*) arg1 <==> arg2

program test
MACRO("(one,two)") ! Only one argument.
MACRO("(one&
&,two)")

end program

Preprocessing produces:

program test
PGF90-W-0225-Argument mismatch for MACRO (macro4.F90: 4)
write(6,*) "(one,two)" <==>  ! Only one argument.
# 6
write(6,*) "(one&
# 6
& <==> two")

end program

If I take away the parenthesis inside the quotes, I get an error (PGF90-S-0229-EOF). The issue doesn’t seem to be related to continuation characters. Standard or not, the preprocessor is most definitely confused.

Thank you.

Standard or not, the preprocessor is most definitely confused.

I don’t disagree but the core issue is that you’re trying to use continuation lines in the macro which isn’t supported. This in turn causes the confusing output.

What behavior are you looking for and what are you trying to accomplish by using the continuation characters? I’m not sure it’s something we can do, but I can put in a request for enhancement (RFE) request.

  • Mat

The problem also depends on the presence of parentheses in the quoted string as well. So it’s kind of weird. Anyway…

We use macros to enable/disable/tag various error and debug reporting messages in our code, most often with FILE and LINE amendments so we can find them when they occur (both in the source and in the output). Sometimes the messages are long and therefore have long format strings. When that occurs, we break them up so we don’t have ridiculously long source lines.

As a workaround, I’ve concatenated them back together. But an RFE would be nice.

Thank you. I very much appreciate the responses.

-Tom

Hi Tom,

I added TPR#21324. Multi-line string literals aren’t supported in C preprocessing and since our preprocessor is based of C, that’s why it doesn’t work. In C, users can work around this by escaping the newline character, but this can’t be used in Fortran. However, it looks like gfortran may have added an extension which allows from multi-line string literals so we’ll see what we can do.

% cat macro2.F90
 #define MACRO(arg1,arg2) write(6,*) arg1 <==> arg2
 MACRO("(one,two)",two) 
 MACRO("(one&
 &,two)",two)
 MACRO("(one,two)",
 two)
 MACRO(__LINE__,
 __FILE__)

 % gfortran -E macro2.F90
 # 1 "macro2.F90"
 # 1 "<built-in>"
 # 1 "<command-line>"
 # 1 "macro2.F90"

 write(6,*) "(one,two)" <==> two 
 write(6,*) "(one& &,two)" <==> two

 write(6,*) "(one,two)" <==> two

 write(6,*) 8 <==> "macro2.F90"


 % pgfortran -E macro2.F90
 # 1 "macro2.F90"
 # 2 "macro2.F90"
 write(6,*) "(one,two)" <==> two 
 write(6,*) "(one& & <==> two",two)
 # 5 "macro2.F90"
 write(6,*) "(one,two)" <==> two
 # 7 "macro2.F90"
 write(6,*) 8 <==> "macro2.F90"

 % cpp macro2.F90
 # 1 "macro2.F90"
 # 1 "<built-in>"
 # 1 "<command-line>"
 # 1 "macro2.F90"

 write(6,*) "(one,two)" <==> two ! Only one argument.
 macro2.F90:3:8: warning: missing terminating " character
 macro2.F90:4:8: warning: missing terminating " character
 write(6,*) "(one& & <==> two
 ",two)
 write(6,*) "(one,two)" <==> two

 write(6,*) 8 <==> "macro2.F90"