Community
cancel
Showing results for 
Search instead for 
Did you mean: 
nemequ
New Contributor I
302 Views

__STDC_NO_THREADS__ undefined

ICC defines __STDC_VERSION__ to 201112L, but doesn't define __STDC_NO_THREADS__.  glibc doesn't currently support the C11 threads API, so it should be defined (per § 6.10.8.3 of the C11 spec).

I know this is partially a libc problem.  I believe GCC resolves this by including <stdc-predef.h> from glibc (which includes a definition of __STDC_NO_THREADS__ in glibc >= 2.16, commit 6d74dd09d29f77ac2b22410f45687def349ba3da).

I'm working around this right now by checking __STDC_NO_THREADS__ after including <limits.h> (<limits.h> includes <features.h> which includes <stdc-predef.h>).

Testing is simple, just put this before any includes:

#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L) && !defined(__STDC_NO_THREADS__)
#  include <threads.h>
#endif
0 Kudos
6 Replies
nemequ
New Contributor I
302 Views

Not sure if you care, but clang has the same issue.  I've reported the bug at http://bugs.llvm.org/show_bug.cgi?id=32377, maybe their response will be helpful.

Judith_W_Intel
Employee
302 Views

 

The Intel compiler doesn't have its own C/C++ libraries or headers, the compiler just use the version on the platform. So if it's fixed in gcc by the glibc that's on the system you'll see it fixed when you use icc as well.

nemequ
New Contributor I
302 Views

It's fixed in GCC because GCC automatically includes <stdc-predef.h> before processing the source files.  The mechanism used for this is documented at https://gcc.gnu.org/onlinedocs/gccint/Misc.html#index-TARGET_005fC_005fPREINCLUDE:

Define this hook to return the name of a header file to be included at the start of all compilations, as if it had been included with #include <file>. If this hook returns NULL, or is not defined, or the header is not found, or if the user specifies -ffreestanding or -nostdinc, no header is included.

This hook can be used together with a header provided by the system C library to implement ISO C requirements for certain macros to be predefined that describe properties of the whole implementation rather than just the compiler. [Emphasis added]

The implementation for glibc is at gcc/config/glibc-c.c.

ICC doesn't do that, which means __STDC_NO_THREADS__ is undefined until it is included by some other glibc header.  In other words, if you try to check __STDC_NO_THREADS__ before including anything else, it will be defined for GCC, but not for ICC.

Perhaps a more complete example would help:

nemequ@peltast:~/t$ cat c11threads.c
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L) && !defined(__STDC_NO_THREADS__)
#  include <threads.h>
#endif

int main(void) {
  return 0;
}
nemequ@peltast:~/t$ gcc -std=c11 c11threads.c && echo Success
Success
nemequ@peltast:~/t$ icc -std=c11 c11threads.c && echo Success
c11threads.c(2): catastrophic error: cannot open source file "threads.h"
  #  include <threads.h>
                        ^

compilation aborted for c11threads.c (code 4)
nemequ@peltast:~/t$ 

 

Judith_W_Intel
Employee
302 Views

 

What operating system are you using? What version of gcc and glibc?

I don't see this with the latest version of gcc (7.0) on RedHat, i.e.:

sptel15-523> cat bug.c

#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L) && !defined(__STDC_NO_THREADS__)
#include <threads.h>
#endif

int main(void) {
  return 0;
}

sptel15-524> gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/site/spt/rdrive/ref/gcc/7-20170319/rhel60/efi2/bin/../libexec/gcc/x86_64-linux-gnu/7.0.1/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../gcc-7-20170319/configure --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --enable-bootstrap --enable-__cxa_atexit --enable-threads=posix --prefix=/home/cmplr/bata/ref/gcc/7-20170319/rhel60/efi2 --with-gmp=/home/cmplr/bata/comp/ia32e/gmp-5.1.3 --with-mpfr=/home/cmplr/bata/comp/ia32e/mpfr-3.1.2 --with-mpc=/home/cmplr/bata/comp/ia32e/mpc-1.0.2 --enable-languages=c,c++,objc,fortran
Thread model: posix
gcc version 7.0.1 20170319 (experimental) (GCC)
sptel15-525> gcc -c -std=c11 bug.c
bug.c:3:10: fatal error: threads.h: No such file or directory
 #include <threads.h>
          ^~~~~~~~~~~
compilation terminated.
sptel15-526>

nemequ
New Contributor I
302 Views

Fedora 25, gcc 6.3.1 and glibc 2.24.

I just checked on Ubuntu 14.04 (gcc 4.9.4) and CentOS 7 (gcc 4.8.5), same result.

Edit: I just checked Fedora rawhide with gcc 7.0.1, and I still get the same result.  It looks like you have a custom build, it seems likely that something is weird with it, since other platforms seem to work as expected…

Judith_W_Intel
Employee
302 Views

 

ok thanks I think I understand why I wasn't seeing the problem.

My machine is set up with GNU 4.4 but we can access other versions of GNU from a non-standard place.

It looks like the preinclude only happens if stdc-predef.h is in /usr/include which only happens if the system has GNU 4.8 or later installed in the standard places.

Anyway this defect has been entered in our internal bugs database as DPD200361219,

A workaround is to explicitly #include <features.h> before any other header files.

Thanks for reporting this problem.

Judy

Reply