Есть ли способ проверить, доступны ли потокобезопасные функции в стандартной библиотеке C?

Что касается поточно-ориентированных функций в новых версиях C стандартная библиотека, есть ли кросс-платформенный способ узнать, доступны ли они через определение препроцессора? Я имею в виду такие функции, как localtime_r().

Если нет стандартного способа, то какой надежный способ в GCC? [EDIT] Или системы posix с unistd.h?


person Peter M    schedule 07.02.2013    source источник
comment
Это то, для чего был создан autoconf.   -  person nneonneo    schedule 08.02.2013
comment
Лучше всего использовать Autoconf. Autoconf создаст тесты для вас.   -  person Dietrich Epp    schedule 08.02.2013
comment
Как и выше, но используйте CMake;)   -  person bkconrad    schedule 08.02.2013
comment
Ле вздох. Разве плохо, если я искренне желал, чтобы автоконф не имел смысла? Но да, я надеялся на идеи препроцессора.   -  person Peter M    schedule 08.02.2013
comment
Если бы это можно было сделать с помощью препроцессора, то не пришлось бы изобретать autoconf, CMake и т.д.   -  person Barmar    schedule 08.02.2013
comment
Эти функции являются обязательными в POSIX, поэтому, если _POSIX_VERSION определяется чем-то, соответствующим относительно последней версии POSIX после включения unistd.h, эти функции должны быть доступны.   -  person R.. GitHub STOP HELPING ICE    schedule 08.02.2013
comment
@R.. В POSIX 2004 это было необязательным. См. tinyurl.com/99tl395 и нажмите ссылку [TSF] рядом с localtime_r. Это стало обязательным только в POSIX 2008, поэтому вам обязательно нужно проверить наличие POSIX 2008 или более поздней версии. Однако тот факт, что _POSIX_VERSION вообще не определен, не означает, что функции не существует. Эта функция также описывается как расширение C и, таким образом, также поддерживается многими платформами, которые не соответствуют POSIX (несмотря на тот факт, что Linux не полностью соответствует POSIX во всех аспектах, даже если он может установить такое определение).   -  person Mecki    schedule 08.02.2013
comment
Ах. Ну, в более ранних версиях POSIX есть другой макрос, _POSIX_THREAD_SAFE_FUNCTIONS, который определен, если он существует. POSIX 2008 требует, чтобы этот макрос был определен.   -  person R.. GitHub STOP HELPING ICE    schedule 08.02.2013
comment
@R.. Я, вероятно, приму ответ Меки, что приятно, но я думаю, что вы очень хорошо ответили на вопрос в своем комментарии для posix-систем (с unitstd.h). Вы должны написать это как реальный ответ!   -  person Peter M    schedule 11.02.2013


Ответы (1)


Не существует стандартного способа проверить это, а значит, нет возможности протестировать его на всех платформах. Такие инструменты, как autoconf, создадут крошечную программу на C, которая вызывает эту функцию, а затем попытаются скомпилировать и скомпоновать ее. Если это работает, похоже, что функция существует, если нет, то ее может не быть (или параметры компилятора неверны и нужно установить соответствующий CFLAGS).

Таким образом, у вас есть в основном 6 вариантов:

  1. Требуйте, чтобы они существовали. Ваш код может работать только на тех платформах, где они существуют; период. Если их нет, компиляция не удастся, но это не ваша проблема, так как платформа нарушает ваши минимальные требования.

  2. Избегайте их использования. Если вы используете не потокобезопасные, возможно, защищенные глобальной блокировкой (например, мьютексом), не имеет значения, существуют они или нет. Конечно, ваш код будет работать только на платформах с мьютексами POSIX, однако, если на платформе нет мьютексов POSIX, у нее также не будет потоков POSIX, а если у нее нет потоков POSIX (и я предполагаю, что вы, вероятно, используете потоки POSIX w /o поддерживает любую альтернативу), зачем вообще беспокоиться о потокобезопасности?

  3. Решите во время выполнения. В зависимости от платформы либо сделайте «слабую ссылку», чтобы вы могли проверить во время выполнения, была ли функция найдена или нет (указатель на функцию будет указывать на NULL, если это не так), или альтернативно разрешите символ динамически, используя что-то например dlsym() (который также не очень переносим, ​​но широко поддерживается в мире Linux/UNIX). Однако в этом случае вам нужен запасной вариант, если функция не найдена во время выполнения.

  4. Используйте такой инструмент, как autoconf, какой-либо другой инструмент с аналогичной функциональностью или ваш собственный сценарий конфигурации, чтобы определить это до начала компиляции (и, возможно, установить макросы препроцессора в зависимости от результата). В этом случае вам также понадобится запасное решение.

  5. Ограничьте использование хорошо известными платформами. Обычно известно, доступна ли эта функция на определенной платформе (и как только она будет доступна, она не исчезнет в будущем). Большинство платформ предоставляют макросы препроцессора, чтобы проверить, что это за платформа, а иногда даже какая ее версия. Например. если вы знаете, что GNU/Linux, Android, Free/Open/NetBSD, Solaris, iOS и MacOS X предлагают эту функцию, проверьте, компилируете ли вы для одной из этих платформ, и если да, используйте ее. Если код скомпилирован для другой платформы (или если вы не можете определить, что это за платформа), он может предлагать или не предлагать эту функцию, но поскольку вы не можете сказать наверняка, лучше перестраховаться и использовать запасной вариант.

  6. Пусть решает пользователь. Либо всегда используйте запасной вариант, если пользователь не сообщил о поддержке, либо делайте наоборот (что, вероятно, имеет больше смысла), всегда предполагайте, что он есть, и в случае сбоя компиляции предложите способ, которым пользователь может принудительно привести ваш код в «совместимость». mode", каким-то образом указав, что потокобезопасные функции недоступны (например, установив переменную среды или используя другую цель make). Конечно, это наименее удобный способ для (бедного) пользователя.

person Mecki    schedule 08.02.2013
comment
@vonbrand Смотрите мой ответный комментарий к комментарию Р.. - person Mecki; 08.02.2013
comment
На самом деле мне нравится комментарий Р.., поскольку он во многом отвечает моему вопросу. По сути, это более конкретный ответ на вашу подчасть (5), к чему я как бы и пришел с моим дополнительным вопросом GCC. Спасибо за запись, очень приятно! - person Peter M; 11.02.2013