【问题标题】:How is using -pthread not violation ODR rules?使用 -pthread 如何不违反 ODR 规则?
【发布时间】:2020-04-03 09:55:33
【问题描述】:

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

在考虑正确的修复方法时,我偶然发现了 Difference between -pthread and -lpthread while compiling。因此,在编译和链接步骤中使用-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 很困难(-pthread, -pthreads, -mthreads,...)

【问题讨论】:

    标签: c++ c pthreads one-definition-rule


    【解决方案1】:

    在 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 进行编译。

    【讨论】:

    • 好的,谢谢。对于那些 C 标准库的实现,它确实会导致 ODR 违规吗?
    猜你喜欢
    • 1970-01-01
    • 2021-12-08
    • 2016-09-13
    • 2011-11-29
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 2019-01-09
    相关资源
    最近更新 更多