Bug 53769 - [C11]: Macros __STDC_NO_THREADS__ / __STDC_NO_ATOMIC__ missing.
Summary: [C11]: Macros __STDC_NO_THREADS__ / __STDC_NO_ATOMIC__ missing.
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.7.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-06-25 17:10 UTC by Patrick Pelissier
Modified: 2021-01-11 21:09 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Patrick Pelissier 2012-06-25 17:10:21 UTC
When building a C program with -std=c11, GCC doesn't define  __STDC_NO_THREADS__ &  __STDC_NO_ATOMIC__ whereas it doesn't support theses features (yet) and still defines __STDC_VERSION__ to 201112L.
Comment 1 jsm-csl@polyomino.org.uk 2012-06-25 18:55:22 UTC
On Mon, 25 Jun 2012, patrick.pelissier at gmail dot com wrote:

> When building a C program with -std=c11, GCC doesn't define 
> __STDC_NO_THREADS__ &  __STDC_NO_ATOMIC__ whereas it doesn't support theses
> features (yet) and still defines __STDC_VERSION__ to 201112L.

C11 support is documented as substantially incomplete.  I believe there is 
work in progress on a branch to add support for the atomics interfaces 
(likely including GCC providing stdatomic.h given how closely related that 
is to the compiler, even though it's not a header required for 
freestanding implmentations).  As for the threading functionality, that's 
substantially a library issue and glibc 2.16 will predefine 
__STDC_NO_THREADS__ in stdc-predef.h to declare the lack of library 
support as of that glibc version.  The final piece is implicit 
preinclusion of stdc-predef.h so that the macros do appear to be defined 
right from the start of the translation unit - I have a 4.8 version of my 
patch <http://gcc.gnu.org/ml/gcc-patches/2009-04/msg01444.html> but need 
to debug problems with its interaction with PCH.
Comment 2 Vincent Lefèvre 2012-06-25 22:37:22 UTC
But what if a recent glibc version isn't used?
Would GCC still be able to compile the following code?

int main (void)
{
#if __STDC_VERSION__ >= 201112L && ! __STDC_NO_THREADS__
  _Thread_local int i = 17;
#endif
  return 0;
}

Shouldn't GCC define __STDC_NO_THREADS__ to 1 by default and stdc-predef.h undefine it if _Thread_local is supported at the library level?
Comment 3 jsm-csl@polyomino.org.uk 2012-06-25 23:32:04 UTC
On Mon, 25 Jun 2012, vincent-gcc at vinc17 dot net wrote:

> But what if a recent glibc version isn't used?

The standard describes cooperating language and library implementations, 
not either on their own.  glibc 2.16 is the first version with any 
significant C11 support (anything beyond quick_exit / at_quick_exit); you 
shouldn't expect the more library-related bits of language support to work 
well without it (or another library whose maintainers have worked with the 
GCC maintainers on areas requiring cooperation, such as this), or the 
library support in glibc to work well without the associated compiler 
support (not all yet implemented, but some parts are in 4.7, in particular 
the built-in functions needed for CMPLX macros, some were in earlier, in 
particular the u"" and U"" support, and more should be in 4.8).

> Would GCC still be able to compile the following code?
> 
> int main (void)
> {
> #if __STDC_VERSION__ >= 201112L && ! __STDC_NO_THREADS__
>   _Thread_local int i = 17;
> #endif

Such a test is not meaningful for documented incomplete support; in the 
absence of claims of conformance, __STDC_VERSION__ can only be interpreted 
as a statement of intent (so far as differences between standard versions 
are implemented, this version has been chosen) rather than as indicating 
that a particular feature is or is not present - that's simply a reality 
of incremental development, partial features are documented as partial and 
you can either work with the features available at a particular time, 
implement the extra ones you want or wait for new versions of all relevant 
components that have the bits you want.  But, at some point I expect to 
implement _Thread_local support and then it will work everywhere __thread 
does (via the existing TLS emulation support, etc., for architectures 
without hardware TLS).  C11 _Thread_local is mainly a keyword alias and 
adjustment of various errors to follow the exact C11 rules; C++11 
thread_local is harder because of the ABI implications of TLS objects with 
static constructors (and the associated interactions with dlopened 
objects).

(The code you give should be rejected if __STDC_NO_THREADS__ is not 
defined, because of the constraint in 6.7.1#3: "In the declaration of an 
object with block scope, if the declaration specifiers include 
_Thread_local, they shall also include either static or extern.".)

> Shouldn't GCC define __STDC_NO_THREADS__ to 1 by default and stdc-predef.h
> undefine it if _Thread_local is supported at the library level?

I think that just makes things unduly complicated.
Comment 4 Vincent Lefèvre 2012-06-26 05:17:31 UTC
(In reply to comment #3)
> Such a test is not meaningful for documented incomplete support; in the 
> absence of claims of conformance, __STDC_VERSION__ can only be interpreted 
> as a statement of intent

OK, this makes clear that for portability, programs should do configure tests instead of relying on the values of standard macros. I think this should be documented in the GCC manual (I haven't checked the latest versions, but there were/are similar problems with C99).

> (The code you give should be rejected if __STDC_NO_THREADS__ is not 
> defined, because of the constraint in 6.7.1#3: "In the declaration of an 
> object with block scope, if the declaration specifiers include 
> _Thread_local, they shall also include either static or extern.".)

Oops, yes, I did a mistake when copying the code: the declaration should have been outside main().
Comment 5 jsm-csl@polyomino.org.uk 2012-06-26 17:13:52 UTC
On Tue, 26 Jun 2012, vincent-gcc at vinc17 dot net wrote:

> OK, this makes clear that for portability, programs should do configure tests
> instead of relying on the values of standard macros. I think this should be

Exactly.  Cf. the issues GCC had with system headers on FreeBSD checking 
__cplusplus to enable C++11 features (where GCC generally has more C++11 
support than Clang, but not the particular feature used by those headers; 
bug 51705).

Eventually there will be features implemented in all compilers people are 
likely to care about and those features can be used without worrying about 
compilers from during the transitional period.  But during the 
transitional period while major features of a new standard such as C++11 
or C11 are being implemented by compilers, you need to test for the 
features you want to use.  And it's entirely plausible that an 
implementation will have fully functional _Thread_local without C11 
threads.h (thread-local storage for pthreads or another form of threads), 
so test for what you actually want to use.
Comment 6 Shawn Landden 2013-12-15 23:29:36 UTC
How do we test for _Thread_local now that it is implemented?
Comment 7 Florian Weimer 2018-07-12 19:23:55 UTC
Furthermore, if I don't misread the standard, the expectation is that if an implementation does not support threads, it still recognizes _Thread_local and mostly ignores it, so that it is available even if __STDC_NO_THREADS__ is not defined.  (Which is of course rather dodgy if you need to conform to an existing ABI for thread-local variables, so I think the committee made a mistake here.)

__STDC_NO_THREADS__ only reflects the existence of the <threads.h> and nothing else.
Comment 8 Vincent Lefèvre 2018-08-26 10:17:24 UTC
(In reply to Florian Weimer from comment #7)
> Furthermore, if I don't misread the standard, the expectation is that if an
> implementation does not support threads, it still recognizes _Thread_local
> and mostly ignores it,

I suppose that the goal is to be able to compile multithread-aware programs on platforms that do not support threads. Since there is only one thread, thread storage duration is equivalent to static storage duration.

> so that it is available even if __STDC_NO_THREADS__
> is not defined.  (Which is of course rather dodgy if you need to conform to
> an existing ABI for thread-local variables, so I think the committee made a
> mistake here.)

The ABI is out of the scope of the standard, so that I don't see any issue here. The conformance to the existing ABI is something above the standard.
Comment 9 Florian Weimer 2018-08-27 18:11:56 UTC
(In reply to Vincent Lefèvre from comment #8)
> (In reply to Florian Weimer from comment #7)
> > Furthermore, if I don't misread the standard, the expectation is that if an
> > implementation does not support threads, it still recognizes _Thread_local
> > and mostly ignores it,
> 
> I suppose that the goal is to be able to compile multithread-aware programs
> on platforms that do not support threads. Since there is only one thread,
> thread storage duration is equivalent to static storage duration.

Exactly.

> > so that it is available even if __STDC_NO_THREADS__
> > is not defined.  (Which is of course rather dodgy if you need to conform to
> > an existing ABI for thread-local variables, so I think the committee made a
> > mistake here.)
> 
> The ABI is out of the scope of the standard, so that I don't see any issue
> here. The conformance to the existing ABI is something above the standard.

But we still have the issue for compilers targeting an ABI which has threads and full thread-local support but which themselves do not support it.  They really should not treat _Thread_local as static storage duration because that would either produce object files which fail to link, or silently corrupt programs (which may even work most of the time).
Comment 10 Christophe Monat 2020-01-15 17:01:42 UTC
Now that C11 is complete, would it be acceptable to have GCC define __STDC_NO_THREADS__ and __STDC_NO_ATOMIC__ when appropriate ?

Beyond the standard that stipulates this behavior, IAR compilers do provide these definitions - at least according to their documentation (IAR C/C++ Development Guide Compiling and Linking - ARM version - 2019). I have not checked other commercial compilers.

This would avoid this behavior of the ARM embedded toolchain:

$ cat samples-threads.c
#if !defined(__STDC_NO_THREADS__)
#include <threads.h>
#endif

$ gcc-arm-none-eabi-8-2019-q3-update/bin/arm-none-eabi-gcc  samples-threads.c
In file included from samples-threads.c:2:
/sw/FROM_sw_st_gnu_compil_comp/comp/arm/linaro/gcc-arm-none-eabi-8-2019-q3-update/arm-none-eabi/include/threads.h:30:10: fatal error: machine/_threads.h: No such file or directory
 #include <machine/_threads.h>
          ^~~~~~~~~~~~~~~~~~~~
Comment 11 jsm-csl@polyomino.org.uk 2020-01-15 22:16:15 UTC
On Wed, 15 Jan 2020, christophe.monat at st dot com wrote:

> Now that C11 is complete, would it be acceptable to have GCC define
> __STDC_NO_THREADS__ and __STDC_NO_ATOMIC__ when appropriate ?

That should be done via the implicit preinclude mechanism, with libc 
providing a header and GCC knowing what libc calls that header.
Comment 12 Patrick Pelissier 2021-01-11 21:09:51 UTC
stdc-predef.h fixes the issue.