Stdlib header interferes with other includes

I’d like to draw your attention to the following issue:

I have a small test case:

#include <string.h>
#include <stdlib.h>
#define copy_free free
static void (*deallocate)(void *pointer) = copy_free;

I compile it using the include path of the HPC SDK:

gcc -O2 -I/opt/bm/nvidia/hpc_sdk229/Linux_x86_64/22.9/compilers/include -c test.c

Which yields the following error message:

test.c:4:19: error: ‘free’ undeclared here (not in a function)
    4 | #define copy_free free
      |                   ^~~~
test.c:6:44: note: in expansion of macro ‘copy_free’
    6 | static void (*deallocate)(void *pointer) = copy_free;
      |                                            ^~~~~~~~~
test.c:2:1: note: ‘free’ is defined in header ‘<stdlib.h>’; did you forget to ‘#include <stdlib.h>’?
    1 | #include <string.h>
  +++ |+#include <stdlib.h>
    2 | #include <stdlib.h>

The HPC SDK has its own stdlib.h file, which invokes #include_next <stdlib.h>. If I remove the #include <string.h> directive, the code compiles. Investigating the pre-processed code (-E option) reveals that in fact no declaration of free is included when #include <string.h> is present. Further, I want to point out that it works fine when only the glibc headers are included. This brings me to the conclusion that something might be wrong with the #include_next directive. Some googling suggests that this feature has been observed to cause trouble in different circumstances.

Unfortunately, I only have an old version of glibc present (2.17) and could not yet check with a newer one.

Another observation is that the issue vanishes when -O0 is used.

Hi Christian,

Sorry but I’m not quite understanding the issue. The system headers we provide are there to work around various GNU extensions, add our own extensions, and resolve compatibility issues. They are not intended for use by gcc.

Is there an issue when using nvc?

-Mat

Hi Mat,

thanks for your answer. In fact, it’s good to know that the headers are not supposed to be fully compatible with gcc.

I obtained all nvc include paths with -drystdinc and using them (in the correct order) makes the test code compile. It also works with nvc but I have to check if this is an option for the original code.

Best regards,
Christian