使用 -pthread 如何不违反 ODR 规则?

How is using -pthread not violation ODR rules?

本文关键字:ODR 规则 何不违 -pthread 使用      更新时间:2023-10-16

我最近通过 CFFI 构建了一个 Python 扩展/包构建,它使用pthread_atfork(和 pthread 互斥锁(但不链接到 pthread,即既不指定-pthread也不指定-lpthread,因此在具有静态部分的系统上失败,该静态部分由于缺少符号而由 libpthread 链接脚本(而不是纯粹的共享库(链接。

在考虑正确的修复程序时,我在编译时偶然发现了 -pthread 和 -lpthread 之间的区别。因此,在编译和链接步骤中使用-pthread不仅可以将-lpthread放置在正确的位置(在上述设置中至关重要(,还可以定义更改函数定义的预处理器符号。

(第三方(函数的一个示例是boost::datetime::c_time::localtime(...)调用localtime_rstd::localtime

这不是(很可能(违反 ODR 的来源吗?因此,例如,编译一个简单的静态库,根本不使用线程而不-pthread并将其链接到一个确实使用线程的二进制文件,因此正在使用-pthread将导致对此类函数的不同定义并成为 UB(/IB?

然而,从我/usr/include/features.h我看到

_REENTRANT, _THREAD_SAFE
Obsolete; equivalent to _POSIX_C_SOURCE=199506L.

所以问题:

是否
  1. /是否由于-pthread而违反ODR,如果是,为什么(是 它不是避免/故意/疏忽(?
  2. 这些定义是否不再相关?那么-pthread现在等同于-lpthread(保存位置(?
  3. 应该使用什么来构建Python的CFFI扩展?由于编译器依赖命名(-pthread, -pthreads, -mthreads,...(,使用-pthread是困难的。

在 Linux 上,标志-pthread而不是-lpthread实际上只是另外将标志-D_REENTRANT传递给 gcc 选项,这在今天已经过时了。

另请参阅features.h中的此评论:

/* Some C libraries once required _REENTRANT and/or _THREAD_SAFE to be
defined in all multithreaded code.  GNU libc has not required this
for many years.  We now treat them as compatibility synonyms for
_POSIX_C_SOURCE=199506L, which is the earliest level of POSIX with
comprehensive support for multithreaded code.  Using them never
lowers the selected level of POSIX conformance, only raises it.  */

但是,可能仍然存在 C 标准库实现,这些实现依赖于编译多线程代码时要定义的_REENTRANT。但是,对于 libc(可能在大多数其他环境中(,您可以安全地使用-lpthread进行编译。