关于较新版本的 C 标准库中的线程安全函数,是否有一种跨平台的方法可以通过预处理器定义来判断这些函数是否可用?我指的是诸如localtime_r()
.
如果没有标准的方式,GCC中可靠的方式是什么?[编辑] 还是带有 unistd.h 的 posix 系统?
没有标准的方法来测试它,这意味着没有办法在所有平台上测试它。类似的工具autoconf
将创建一个调用此函数的微型 C 程序,然后尝试编译和链接它。它有效,看起来该函数存在,如果不存在,则它可能不存在(或编译器选项错误,CFLAGS
需要设置适当的)。
所以你基本上有6个选择:
要求他们存在。您的代码只能在它们存在的平台上运行;时期。如果它们不存在,编译将失败,但这不是您的问题,因为平台违反了您的最低要求。
避免使用它们。如果您使用非线程安全的,可能受全局锁(例如互斥锁)保护,它们是否存在并不重要。当然,您的代码只能在具有 POSIX 互斥锁的平台上工作,但是,如果平台没有 POSIX 互斥锁,它也不会有 POSIX 线程,如果它没有 POSIX 线程(我猜你可能正在使用 POSIX 线程 w /o 支持任何替代方案),你为什么要首先担心线程安全?
在运行时决定。根据平台,要么做一个“弱链接”,所以你可以在运行时测试是否找到了函数(指向函数的指针将指向NULL
如果它不是)或者使用类似的东西动态解析符号dlsym()
(这也不是真正可移植的,但在 Linux/UNIX 世界中得到广泛支持)。但是,在这种情况下,如果在运行时未找到该函数,则需要回退。
使用类似的工具autoconf
、其他具有类似功能的工具或您自己的配置脚本在开始编译之前确定这一点(并且可能根据结果设置预处理器宏)。在这种情况下,您还需要一个备用解决方案。
限制使用知名平台。这个功能在某个平台上是否可用通常是已知的(一旦可用,以后也不会消失)。大多数平台都公开了预处理器宏来测试这是什么类型的平台,有时甚至是哪个版本。例如,如果您知道 GNU/Linux、Android、Free/Open/NetBSD、Solaris、iOS 和 MacOS X 都提供此功能,请测试您是否正在为这些平台之一进行编译,如果是,请使用它。如果代码是为另一个平台编译的(或者如果您无法确定是哪个平台),它可能会或可能不会提供此功能,但由于您无法确定,最好安全并使用后备。
让用户决定。要么总是使用后备,除非用户已经表示支持或者反过来做(这可能更有意义),总是假设它在那里,万一编译失败,提供一种用户可以强制你的代码进入“兼容性”的方法mode”,通过某种方式指定线程安全函数不可用(例如,通过设置环境变量或使用不同的 make 目标)。当然,对于(可怜的)用户来说,这是最不方便的方法。