-Mcpp does not resolve macros in #pragma statements


for the following example, I get not the expected result:

$ pgcc --version

pgcc 18.4-0 64-bit target on x86-64 Linux -tp haswell 
PGI Compilers and Tools
Copyright (c) 2018, NVIDIA CORPORATION.  All rights reserved.
$ cat >test-cpp-pragma.c <<EOF
#define foo bar
#pragma omp parallel foo
$ pgcc -Mcpp -mp test-cpp-pragma.c -o test-cpp-pragma.i
$ cat 

#pragma omp parallel foo

Where my expected result would be:

#pragma omp parallel bar

pgcc -E does resolve it, even without specifying -mp. And for reference ‘gcc’, ‘cpp’, and ‘icc’ only resolve it, if the OpenMP flag -fopenmp/-qopenmp is given.

Hi Bert,

I’m seeing the same behavior on my end. I’ve reported it to engineering (TPR#25986). I’ll post an update should anything change.

  • Alex

Hi Bert,

Could you give me a little more detail as to the kind of impact this behavior has on your codebase? In other words, is this an essential feature or simply desirable?

Dear Alex,

the bigger picture is, ahm, bigger:

We have a workflow of source-to-source instrumentation, which is roughly:

  1. pre-process source
  2. modify source, which includes adding #include and #define statements and use macros in #pragma omp statements
  3. compile source with preprocessing on (i.e., its not a .i file)

When using ‘pgcc -E’ as the preprocessor, we get double the -preinclude _c_macros.h file, which results in errors because of redefinition of struct __va_list_tag.

I was looking into the -Mcpp option than.

If I use ‘pgcc -Mcpp’ for step one, than I get errors, because of a wrongly included gcc header:

$ pgcc --version

pgcc 18.4-0 64-bit target on x86-64 Linux -tp haswell 
PGI Compilers and Tools
Copyright (c) 2018, NVIDIA CORPORATION.  All rights reserved.
$ cat >empty.c <<EOF 
#include <stdint.h>

#ifdef _OPENMP
#include <omp.h>
$ pgcc -mp -Mcpp=nocomment,line empty.c 
PREPRO-I-0222-Redundant definition for symbol __extension__ (/usr/include/x86_64-linux-gnu/sys/cdefs.h: 367)
$ pgcc -mp -c empty.i
PGC-S-0040-Illegal use of symbol, __INT_LEAST8_TYPE__ (/usr/lib/gcc/x86_64-linux-gnu/7/include/stdint-gcc.h: 60)
PGC-W-0156-Type not specified, 'int' assumed (/usr/lib/gcc/x86_64-linux-gnu/7/include/stdint-gcc.h: 60)

The stdint-gcc.h header is not included, when preprocessed with -E though.

Note also, that ‘-Mcpp -mp’ does not #define _OPENMP.

Next I tried to use -Mcpp for the preprocessing in step 3, i.e., splitting this step into 2.

3a. pre-process with -Mcpp into an .i file
3b. compile .i file, which disables pre-processing

And here the pre-processing with -Mcpp does not resolve the macros in the #pragma statements.

I thought, it maybe simpler to try to get this second approach working, but maybe it is also possible to prevent the -preinclude of _c_macros.h somehow?


Use -E or -P in step #1 and also add --no_preincludes. You should be able to use --no_preincludes at step #1 or step #3 (not both). Try it both ways and write back with your results.

Thanks, that worked. Except, that I now get zillions of warnings of the kind:

PGC-W-0251-Extraneous tokens ignored following # directive (empty.prep.c: 93)

The reason is the <System_Header> at the end of #-line statements:

# 1 "empty.c"
# 0 "empty.c"
# 1 "/home/wesarg/opt/pgi-18.4/linux86-64-llvm/18.4/include/_c_macros.h" <System_Header>

Can this warning be suppressed?

Try adding -silent, should be the same as -Minform=severe

You can see all of the available options with pgcc -help

Thanks for the hammer, but I expected a tweezer for this problem ;-)

Anyway, as this # line comes from the preprocessor itself, I think it would make much more sense, that the preprocessor itself does not issue such warnings to begin with, if it encounter such line in its input. More ‘tokens’ after the filename string is rather common in the output of preprocessors. GNU documents them here: