`__noinline__` macro conflict between GLib and CUDA
Hi,
7 months ago there was a macro conflict with Pixman's noinline
, which was fixed here: !2059 (merged)
It seems that the fix introduced a new conflict with cuda's __noinline__
macro. From what I gather, gcc's documentation suggests that any attribute name with double underscores is safe to use in header files. That seems to exclude compiler reserved macros, and if NVCC counts as a compiler, it's allowed to reserve macros like __noinline__
. My guess is that the GLib originally excluded double underscores on noinline because of CUDA, but it wasn't documented, so it was assumed to be a typo and changed in the merge above.
I'm not sure I've quite got to the bottom of it, but whatever the cause, since upgrading my version of glib from 2.62.3 to 2.70.2 I get the following error when compiling a .cu file with NVCC that includes both glib.h and cuda_runtime.h:
.../include/glib-2.0/glib/gmacros.h:248:28: error: missing ')' after "__has_attribute"
248 | #if g_macro__has_attribute(__noinline__)
.../include/crt/host_defines.h:83:23: error: missing binary operator before token "("
83 | __attribute__((noinline))
.../include/glib-2.0/glib/gmacros.h:248:28: note: in expansion of macro '__noinline__'
248 | #if g_macro__has_attribute(__noinline__)
Here's the relevant docs from GCC:
GCC documentation says: "You may optionally specify attribute names with ‘__’ preceding and following the name. This allows you to use them in header files without being concerned about a possible macro of the same name. For example, you may use the attribute name
__noreturn__
instead of noreturn."
and comments in CUDA where they define the macro:
#if defined(__CUDACC__) || defined(__CUDA_ARCH__) || defined(__CUDA_LIBDEVICE__)
/* gcc allows users to define attributes with underscores,
e.g., __attribute__((__noinline__)).
Consider a non-CUDA source file (e.g. .cpp) that has the
above attribute specification, and includes this header file. In that case,
defining __noinline__ as below would cause a gcc compilation error.
Hence, only define __noinline__ when the code is being processed
by a CUDA compiler component.
*/
#define __noinline__ \
__attribute__((noinline))
I checked on stack overflow before raising the issue here, there's a mix of advice and opinions there: https://stackoverflow.com/questions/70301375/noinline-macro-conflict-between-glib-and-cuda/
As I say there, I'm reasonably new to both CUDA and GLib, it's entirely possible I've misunderstood something. Let me know if more info or testing is required. Any advice on a workaround in the meantime would also be appreciated. For the moment I'm going to do the following:
#undef __noinline__
#include <glib.h>
#if defined(__CUDACC__) || defined(__CUDA_ARCH__) || defined(__CUDA_LIBDEVICE__)
#define __noinline__ __attribute__((noinline))
#endif
Environment: glib 2.70.2, cuda 10.2.89, gcc 9.4.0, on Linux.