5

I've recently come about a Python extension/package build via CFFI which uses pthread_atfork (and a pthread mutex) but does not link against pthread, i.e. specifies neither -pthread nor -lpthread and hence fails on systems which have a static part which is linked in by a libpthread link script (as opposed to a purely shared library) due to missing symbols.

When thinking about the correct fix I stumbled over the Difference between -pthread and -lpthread while compiling. So using -pthread on compile and link step does not only place -lpthread at the correct position (crucial in the above setup) but also defines preprocessor symbols which change definitions of functions.

An example of a (third-party) function is boost::datetime::c_time::localtime(...) which calls either localtime_r or std::localtime.

Isn't that a (very likely) source for ODR violations? So e.g. compiling a simple static library not using threads at all without -pthread and linking that into a binary which does use threads and hence is using -pthread will lead to different definitions of such a function and be UB(/IB?)?

However from my /usr/include/features.h I see

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

So questions:

  1. Are/were there ODR violations due to -pthread and if so why (was it not avoided/on purpose/an oversight)?
  2. Are those definitions no longer relevant? So -pthread is now equivalent to -lpthread (save the placement)?
  3. What should one use to build a CFFI extension for Python? Using -pthread is difficult due to compiler dependent naming (-pthread, -pthreads, -mthreads, ...)
LPs
  • 16,045
  • 8
  • 30
  • 61
Flamefire
  • 5,313
  • 3
  • 35
  • 70

1 Answers1

4

On Linux, the flag -pthread as opposed to -lpthread indeed only additionally passes the flag -D_REENTRANT to the gcc options, which is obsolete nowadays.

See also this comment in 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.  */

However, there might still be C standard library implementations, which rely on _REENTRANT to be defined when compiling multithreaded code. For libc (and probably in most other environments) however, you can safely use -lpthread for compiling.

Ctx
  • 18,090
  • 24
  • 36
  • 51
  • Alright thanks. And for those C standard library implementations does it indeed lead to ODR violations? – Flamefire Dec 10 '19 at 11:23