A preprocessor macro called _GLIBCXX_USE_NANOSLEEP appears in two standard header files:
- c++/4.7.1/x86_64-unknown-linux-gnu/bits/c++config.h
- c++/4.7.1/thread
In a default build of GCC 4.7.1 (Linux, 64-bit) the only thing c++config.h includes is this comment:
/* Defined if nanosleep is available. */
/* #undef _GLIBCXX_USE_NANOSLEEP */
Whereas in thread, the definition of std::this_thread::sleep_for() and std::this_thread::sleep_until() depend on the macro to be defined. If it isn’t defined, both functions – although required by the C++ Standard – won’t be defined either.
On my system (glibc 2.15), the macro is not defined, although the nanosleep() function (declared in ctime) exists and is operational.
I’d like to know what this is all about and how to deal with it. Specifically:
- Is there a configuration option that should be used when building GCC to activate this macro by default, as suggested by this post? (I couldn’t find any in the online documentation of the build process.)
- Is there really a relation between the
nanosleep()function and the macro? The declaration ofnanosleep()inctime/time.hdoes not seem to depend on, or define, the macro. - Is there any specific risk involved in defining the macro in my own header files, or as a
-Doption on the command line (as suggested in this related question)? What if I do this on a system wherenanosleep()is not available, and how can I actually find out?
Update From GCC 4.8 onwards, support for std::this_thread::sleep_for() and the like is automatically included in libstdc++. No configuration flag is required any more. From the GCC 4.8 change log:
this_thread::sleep_for(), this_thread::sleep_until() and this_thread::yield() are defined without requiring the configure option –enable-libstdcxx-time;
But note the further details on this for GCC 4.8 and 4.9 given in Jonathan’s answer.
When libstdc++ is built its
configurescript tests your system to see what features are supported, and based on the results it defines (or undefines) various macros inc++config.hIn your case
configuredetermined that the POSIXnanosleep()function is not available and the macro is not defined. However, as you say,nanosleep()is available on your system. The reason it’s not enabled byconfigureis that the checks for it don’t even run unless you use the--enable-libstdcxx-timeoption (documented in the Configuration chapter of the libstdc++ manual, not the GCC configure docs)Yes,
--enable-libstdcxx-timeThe declaration of glibc’s function doesn’t depend on libstdc++’s macro, no. But the macro tells libstdc++ whether to use the function or not.
It’s naughty and is unsupported, but will work. The macro is an internal implementation detail that should be set by configure and not by users and changing the definition of the implementation’s internal macros can break things. But in this case it won’t because the only code that depends on it is in a header, no library code in
libstdc++.sois affected.But it would be better to reinstall GCC and use the
--enable-libstdcxx-timeoption, or if that’s not possible edit yourc++config.hto define the macro to true.If you define it on a different system where
nanosleep()isn’t available you’ll get a compilation error when you#include <thread>.I have some ideas for improving that configuration, so
nanosleep()andsched_yield()will be checked for by default, but I haven’t had time to work on them yet.Update: I’ve committed some changes so that building GCC 4.8 without
--enable-libstdcxx-timewill still definestd::this_thread::yield()(as a no-op) and will implementstd::this_thread::sleep_for()andstd::this_thread::sleep_until()using the lower resolution::sleep()and::usleep()functions instead of::nanosleep(). It’s still better to define--enable-libstdcxx-timethough.Another update: GCC 4.9.0 is out and now defaults to automatically enabling
nanosleepandsched_yieldon platforms that are known to support them. There is no longer any need to use--enable-libstdcxx-time.