Ответ 1
Когда libstdС++ построен, его configure
script проверяет вашу систему, чтобы увидеть, какие функции поддерживаются, и на основе результатов он определяет (или отменяет) различные макросы в c++config.h
В вашем случае configure
определено, что функция POSIX nanosleep()
недоступна, и макрос не определен. Однако, как вы говорите, nanosleep()
доступен в вашей системе. Причина, по которой она не включена configure
, заключается в том, что проверки для нее даже не выполняются, если вы не используете параметр --enable-libstdcxx-time
(задокументированный в главе в руководстве по libstdС++, а не GCC configure docs)
- Есть ли опция конфигурации, которая должна использоваться при создании GCC для активации этого макроса по умолчанию, как это предлагается в этом сообщении? (Я не смог найти в онлайн-документации процесса сборки.)
Да, --enable-libstdcxx-time
- Есть ли связь между функцией nanosleep() и макросом? Объявление nanosleep() в ctime/time.h, похоже, не зависит от макроса или не определяет его.
Объявление функции glibc не зависит от макроса libstdС++, no. Но макрос сообщает libstdС++, следует ли использовать функцию или нет.
- Существует ли какой-либо конкретный риск при определении макроса в моих собственных файлах заголовков или в качестве опции -D в командной строке (как это предлагается в этом связанном вопросе)? Что делать, если я делаю это в системе, где nanosleep() недоступен, и как я могу узнать?
Это непослушный и неподдерживаемый, но будет работать. Макрос - это внутренняя деталь реализации, которая должна быть задана настройкой, а не пользователями, а изменение определения внутренних макросов реализации может нарушить ситуацию. Но в этом случае это произойдет не потому, что единственный код, который зависит от него, находится в заголовке, никакой код библиотеки в libstdc++.so
не будет затронут.
Но лучше было бы переустановить GCC и использовать параметр --enable-libstdcxx-time
, или если это невозможно, отредактируйте свой c++config.h
, чтобы определить макрос в true.
Если вы определяете его в другой системе, где nanosleep()
недоступен, вы получите ошибку компиляции, когда вы #include <thread>
.
У меня есть некоторые идеи для улучшения этой конфигурации, поэтому nanosleep()
и sched_yield()
будут проверяться по умолчанию, но у меня не было времени на работу на них еще.
Обновление: Я внес некоторые изменения, так что построение GCC 4.8 без --enable-libstdcxx-time
будет по-прежнему определять std::this_thread::yield()
(как нет-op) и будет реализовывать std::this_thread::sleep_for()
и std::this_thread::sleep_until()
используя функции меньшего разрешения ::sleep()
и ::usleep()
вместо ::nanosleep()
. Однако еще лучше определить --enable-libstdcxx-time
.
Другое обновление: GCC 4.9.0 отсутствует и теперь по умолчанию автоматически включает nanosleep
и sched_yield
на платформах, которые, как известно, поддерживают их. Больше не нужно использовать --enable-libstdcxx-time
.