Problematic inclusion of "pthread.h".

When compiling the smart pointer tests with gcc 3.4.2 on Tru64, two tests fail with an error message. (See http://tinyurl.com/4jngu ) As far as I can see, the shared pointer implementation at some point includes the "pthread.h" system header file but gcc on Tru64 requires that -pthread must be specified on the command line when including this header file. When running this test with gcc 3.4.2 on Linux the file "pthread.h" is also included but gcc doesn't require the addition of -pthread in the command line on this platform. This leads to the question whether it is ok to include "pthread.h" without specifying -pthread on the command line. Does anyone know an answer to this? Markus

On Tue, Oct 05, 2004 at 03:05:13PM +0200, Markus Sch?pflin wrote:
When compiling the smart pointer tests with gcc 3.4.2 on Tru64, two tests fail with an error message. (See http://tinyurl.com/4jngu )
As far as I can see, the shared pointer implementation at some point includes the "pthread.h" system header file but gcc on Tru64 requires that -pthread must be specified on the command line when including this header file.
When running this test with gcc 3.4.2 on Linux the file "pthread.h" is also included but gcc doesn't require the addition of -pthread in the command line on this platform.
This leads to the question whether it is ok to include "pthread.h" without specifying -pthread on the command line. Does anyone know an answer to this?
Short answer: yes, it's OK. Long answer: On Linux, with GCC, yes, it's fine. libstdc++ does this itself. When configured to use pthreads (*) the library includes gthr-posix.h, which unconditionally includes pthread.h At link time, if -pthread wasn't given, the pthread_xxx() symbols declared in pthread.h aren't found and so the linker falls back to weak symbols defined in the libstdc++ library (which are just stubs that do nothing). I'm not so sure about other POSIX platforms, just Linux. jon (*) N.B. configuring the compiler to use threads does NOT mean you always compile with pthreads, it means you have the _option_ of compiling with -pthread. If the compiler isn't configured to use threads then you can't use -pthread at all. -- "Live fast, die old, and make very sure everyone knows you were there." - Alan Cox

When compiling the smart pointer tests with gcc 3.4.2 on Tru64, two tests fail with an error message. (See http://tinyurl.com/4jngu )
As far as I can see, the shared pointer implementation at some point includes the "pthread.h" system header file but gcc on Tru64 requires that -pthread must be specified on the command line when including this header file.
When running this test with gcc 3.4.2 on Linux the file "pthread.h" is also included but gcc doesn't require the addition of -pthread in the command line on this platform.
This leads to the question whether it is ok to include "pthread.h" without specifying -pthread on the command line. Does anyone know an answer to this?
I think on some platforms <pthread.h> doesn't compile unless _REENTRANT or some similar compiler-specific magic symbol is defined: in other words it's an assert that the compiler is indeed in thread safe mode. It looks to me as though BOOST_HAS_THREADS is getting set unconditionally for gcc on this platform, and presumably we should only set it when _REENTRANT is defined (I'm assuming that's the symbol that gets defined when the -thread option is used - can you check?). Hold on... checked the output from config_info and looks as though _REENTRANT *is* defined, so I'm mystified. I also note that the platform is detected as "generic unix". Do you know what macros gcc defines to identify this platform? Thanks, John.

John Maddock wrote:
When compiling the smart pointer tests with gcc 3.4.2 on Tru64, two tests fail with an error message. (See http://tinyurl.com/4jngu )
As far as I can see, the shared pointer implementation at some point includes the "pthread.h" system header file but gcc on Tru64 requires that -pthread must be specified on the command line when including this header file.
When running this test with gcc 3.4.2 on Linux the file "pthread.h" is also included but gcc doesn't require the addition of -pthread in the command line on this platform.
This leads to the question whether it is ok to include "pthread.h" without specifying -pthread on the command line. Does anyone know an answer to this?
I think on some platforms <pthread.h> doesn't compile unless _REENTRANT or some similar compiler-specific magic symbol is defined: in other words it's an assert that the compiler is indeed in thread safe mode.
Yes, it's true. _REENTRANT has to be defined, there is an explicit check in "pthread.h" for this.
It looks to me as though BOOST_HAS_THREADS is getting set unconditionally for gcc on this platform, and presumably we should only set it when _REENTRANT is defined (I'm assuming that's the symbol that gets defined when the -thread option is used - can you check?).
Hold on... checked the output from config_info and looks as though _REENTRANT *is* defined, so I'm mystified. I also note that the platform is detected as "generic unix". Do you know what macros gcc defines to identify this platform?
Attached is the output of "gcc -ansi -dM". I hope it contains enough information to answer your questions. Note also that _REENTRANT is not defined here, therefore its source must be somewhere outside of gcc. Markus #define __DBL_MIN_EXP__ (-1021) #define __FLT_MIN__ 1.17549435e-38F #define __CHAR_BIT__ 8 #define __WCHAR_MAX__ 4294967295U #define __DBL_DENORM_MIN__ 4.9406564584124654e-324 #define __FLT_EVAL_METHOD__ 0 #define __alpha_bwx__ 1 #define __DBL_MIN_10_EXP__ (-307) #define __FINITE_MATH_ONLY__ 0 #define __LP64__ 1 #define __GNUC_PATCHLEVEL__ 2 #define __SHRT_MAX__ 32767 #define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L #define __SYSTYPE_BSD 1 #define __unix 1 #define __alpha_ev5__ 1 #define __LDBL_MAX_EXP__ 16384 #define __LANGUAGE_C_PLUS_PLUS 1 #define __SCHAR_MAX__ 127 #define __USER_LABEL_PREFIX__ #define __STDC_HOSTED__ 1 #define __osf__ 1 #define __LDBL_HAS_INFINITY__ 1 #define __DBL_DIG__ 15 #define __FLT_EPSILON__ 1.19209290e-7F #define __GXX_WEAK__ 0 #define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L #define __digital__ 1 #define __unix__ 1 #define __DECIMAL_DIG__ 36 #define __LDBL_HAS_QUIET_NAN__ 1 #define _REENTRANT 1 #define __GNUC__ 3 #define __DBL_MAX__ 1.7976931348623157e+308 #define __DBL_HAS_INFINITY__ 1 #define __X_FLOAT 1 #define __STRICT_ANSI__ 1 #define __cplusplus 1 #define __DEPRECATED 1 #define __DBL_MAX_EXP__ 1024 #define __GNUG__ 3 #define __LANGUAGE_C_PLUS_PLUS__ 1 #define __LONG_LONG_MAX__ 9223372036854775807LL #define __GXX_ABI_VERSION 1002 #define __FLT_MIN_EXP__ (-125) #define __DBL_MIN__ 2.2250738585072014e-308 #define __FLT_MIN_10_EXP__ (-37) #define __DBL_HAS_QUIET_NAN__ 1 #define __REGISTER_PREFIX__ #define __NO_INLINE__ 1 #define __FLT_MANT_DIG__ 24 #define __VERSION__ "3.4.2" #define __PRAGMA_EXTERN_PREFIX 1 #define __alpha 1 #define __SIZE_TYPE__ long unsigned int #define __FLT_RADIX__ 2 #define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L #define __FLT_HAS_QUIET_NAN__ 1 #define __FLT_MAX_10_EXP__ 38 #define __LONG_MAX__ 9223372036854775807L #define __FLT_HAS_INFINITY__ 1 #define _SYSTYPE_BSD 1 #define __STDC_VERSION__ 199409L #define __EXCEPTIONS 1 #define __LDBL_MANT_DIG__ 113 #define _LONGLONG 1 #define __WCHAR_TYPE__ unsigned int #define __FLT_DIG__ 6 #define __INT_MAX__ 2147483647 #define __LONG_DOUBLE_128__ 1 #define __FLT_MAX_EXP__ 128 #define __DBL_MANT_DIG__ 53 #define __WINT_TYPE__ unsigned int #define __LDBL_MIN_EXP__ (-16381) #define __WCHAR_UNSIGNED__ 1 #define __LDBL_MAX_10_EXP__ 4932 #define __DBL_EPSILON__ 2.2204460492503131e-16 #define _LP64 1 #define __FLT_DENORM_MIN__ 1.40129846e-45F #define __FLT_MAX__ 3.40282347e+38F #define __GNUC_MINOR__ 4 #define __DBL_MAX_10_EXP__ 308 #define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L #define __SYSTYPE_BSD__ 1 #define __PTRDIFF_TYPE__ long int #define __arch64__ 1 #define __LDBL_MIN_10_EXP__ (-4931) #define __alpha__ 1 #define __LDBL_DIG__ 33

On Tue, Oct 05, 2004 at 06:05:54PM +0200, Markus Schöpflin wrote:
John Maddock wrote:
[...]
I think on some platforms <pthread.h> doesn't compile unless _REENTRANT or some similar compiler-specific magic symbol is defined: in other words it's an assert that the compiler is indeed in thread safe mode.
Yes, it's true. _REENTRANT has to be defined, there is an explicit check in "pthread.h" for this.
It looks to me as though BOOST_HAS_THREADS is getting set unconditionally for gcc on this platform, and presumably we should only set it when _REENTRANT is defined (I'm assuming that's the symbol that gets defined when the -thread option is used - can you check?).
Hold on... checked the output from config_info and looks as though _REENTRANT *is* defined, so I'm mystified. I also note that the platform is detected as "generic unix". Do you know what macros gcc defines to identify this platform?
Attached is the output of "gcc -ansi -dM". I hope it contains enough information to answer your questions. Note also that _REENTRANT is not defined here, therefore its source must be somewhere outside of gcc.
_REENTRANT is most likely be set by libstdc++-v3. IIRC, the standard library that ships with gcc 3.4.x defines it, e.g., in (some file included by) string.h, no matter whether you provided `-pthread' (or `-thread' on your platform) or not. string.h is included by config_info.cpp whence config_info reports _REENTRANT as set. Regards Christoph -- http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/cludwig.html LiDIA: http://www.informatik.tu-darmstadt.de/TI/LiDIA/Welcome.html

Markus Schöpflin wrote:
Attached is the output of "gcc -ansi -dM". I hope it contains enough information to answer your questions. Note also that _REENTRANT is not defined here, therefore its source must be somewhere outside of gcc.
...
#define __digital__ 1 #define __unix__ 1 #define __DECIMAL_DIG__ 36 #define __LDBL_HAS_QUIET_NAN__ 1
#define _REENTRANT 1
#define __GNUC__ 3 #define __DBL_MAX__ 1.7976931348623157e+308 #define __DBL_HAS_INFINITY__ 1
... Looks like _REENTRANT is defined to 1.

Peter Dimov wrote:
Markus Schöpflin wrote:
Attached is the output of "gcc -ansi -dM". I hope it contains enough information to answer your questions. Note also that _REENTRANT is not defined here, therefore its source must be somewhere outside of gcc.
...
#define __digital__ 1 #define __unix__ 1 #define __DECIMAL_DIG__ 36 #define __LDBL_HAS_QUIET_NAN__ 1
#define _REENTRANT 1
#define __GNUC__ 3 #define __DBL_MAX__ 1.7976931348623157e+308 #define __DBL_HAS_INFINITY__ 1
...
Looks like _REENTRANT is defined to 1.
Argl, I hate when this happens. I ran the test with gcc, then started writing the mail and attached the output, then repeated the test with -pthread on the command line (which overwrote the output of the previous test) and then I sent the mail. :-( Attached is once more the output of the predefined macros. This time, no _REENTRANT is present. The exact command used was "gcc -ansi -dM -E". Sorry for the confusion, Markus

Attached is the output of "gcc -ansi -dM". I hope it contains enough information to answer your questions. Note also that _REENTRANT is not defined here, therefore its source must be somewhere outside of gcc.
I've been trying to reproduce this using HP's test drive machines, unfortunately they all use single-threaded gcc :-(
From all that's been said it's apparent that _REENTRANT is getting set by one of the gcc headers, but which one? This is important because we have a consistency problem otherwise (threading support getting turned on depending on which headers you happen to have included).
I've attached an updated version of boost/config/stdlib/libstdcpp3.hpp, can you see if this fixes the issue? If it does then either commit it or let me know and I'll commit it. John.

On Wed, Oct 06, 2004 at 12:36:58PM +0100, John Maddock wrote:
Attached is the output of "gcc -ansi -dM". I hope it contains enough information to answer your questions. Note also that _REENTRANT is not defined here, therefore its source must be somewhere outside of gcc.
I've been trying to reproduce this using HP's test drive machines, unfortunately they all use single-threaded gcc :-(
From all that's been said it's apparent that _REENTRANT is getting set by one of the gcc headers, but which one? This is important because we have a consistency problem otherwise (threading support getting turned on depending on which headers you happen to have included).
All of the libstdc++ headers will end up including gthr-default.h which will define _REENTRANT. This is planned to be fixed (see PR 11953) but I don't know when, possibly 4.0 now. Shouldn't the attached header test __osf__ not __osl__ ? jon -- "There are only two industries that refer to their customers as 'users'." - Edward Tufte

On Wed, Oct 06, 2004 at 12:36:58PM +0100, John Maddock wrote:
#ifdef __GLIBCXX__ // gcc 3.4 and greater: # ifdef _GLIBCXX_HAVE_GTHR_DEFAULT // // If the std lib has thread support turned on, then turn it on in Boost // as well. We do this because some gcc-3.4 std lib headers define _REENTANT // while others do not... // # define BOOST_HAS_THREADS # else # define BOOST_DISABLE_THREADS # endif #endif
John, this comment (which is in the current version in CVS) is misleading, and IMHO the whole thing is redundant. If *any* 3.4 libstdc++ header is included and _GLIBCXX_HAVE_GTHR_DEFAULT is defined then gthr-default.h will be included and therefore _REENTRANT will be defined, and therefore BOOST_HAS_THREADS will be defined anyway by boost/config/suffix.hpp (this is the case for GCC configured for MT support.) If _GLIBCXX_HAVE_GTHR_DEFAULT is not defined then gthr-default.h will not be included, and _REENTRANT will not be defined, and BOOST_DISABLE_THREADS will be defined by boost/config/suffix.hpp (this is the case for GCC configured with no support for MT.) I don't think that bit of preprocessor code changes anything (but I might be wrong again) jon -- "It is seldom that liberty of any kind is lost all at once." - David Hume

John, this comment (which is in the current version in CVS) is misleading, and IMHO the whole thing is redundant.
If *any* 3.4 libstdc++ header is included and _GLIBCXX_HAVE_GTHR_DEFAULT is defined then gthr-default.h will be included and therefore _REENTRANT will be defined, and therefore BOOST_HAS_THREADS will be defined anyway by boost/config/suffix.hpp (this is the case for GCC configured for MT support.)
If _GLIBCXX_HAVE_GTHR_DEFAULT is not defined then gthr-default.h will not be included, and _REENTRANT will not be defined, and BOOST_DISABLE_THREADS will be defined by boost/config/suffix.hpp (this is the case for GCC configured with no support for MT.)
I don't think that bit of preprocessor code changes anything (but I might be wrong again)
You're right, for some reason I thought we were dealing with gcc-3.3, but as you say it is indeed 3.4. In which case I'm lost as to why the config headers aren't doing the right thing anyway - including <utility> should be enough solve the issue as it does on linux :-( Thanks, John.

John Maddock wrote:
In which case I'm lost as to why the config headers aren't doing the right thing anyway - including <utility> should be enough solve the issue as it does on linux :-(
I think I found the reason why it doesn't work. As we all known by now, _REENTRANT is defined in a header included by "gthr.h". schoepf@AREA51:/opt/gcc/include/c++/3.4.2> /usr/local/bin/grep -r "gthr.h" . ./fstream:#include <bits/gthr.h> ./bits/concurrence.h:#include "bits/gthr.h" ./bits/locale_classes.h:#include <bits/gthr.h> ./bits/stl_threads.h:// The only supported threading model is GCC's own gthr.h abstraction ./bits/stl_threads.h:#include "bits/gthr.h" ./ext/bitmap_allocator.h:#include <bits/gthr.h> ./ext/mt_allocator.h:#include <bits/gthr.h> ./ext/rope:# include <bits/gthr.h> ./ext/rope:#error __GTHREAD_MUTEX_INIT or __GTHREAD_MUTEX_INIT_FUNCTION should be defined by gthr.h abstraction layer, report problem to libstdc++@gcc.gnu.org. ./alphaev56-dec-osf5.1/bits/c++io.h:#include <bits/gthr.h> And none of these headers is included by <utility>. But as soon as you use any I/O headers, the file gets included via "c++io.h" which is included by <iosfwd>. :-( What a mess!!! Markus

On Thu, Oct 07, 2004 at 04:24:56PM +0200, Markus Sch?pflin wrote:
John Maddock wrote:
In which case I'm lost as to why the config headers aren't doing the right thing anyway - including <utility> should be enough solve the issue as it does on linux :-(
I think I found the reason why it doesn't work. As we all known by now, _REENTRANT is defined in a header included by "gthr.h".
schoepf@AREA51:/opt/gcc/include/c++/3.4.2> /usr/local/bin/grep -r "gthr.h" . ./fstream:#include <bits/gthr.h> ./bits/concurrence.h:#include "bits/gthr.h" ./bits/locale_classes.h:#include <bits/gthr.h> ./bits/stl_threads.h:// The only supported threading model is GCC's own gthr.h abstraction ./bits/stl_threads.h:#include "bits/gthr.h" ./ext/bitmap_allocator.h:#include <bits/gthr.h> ./ext/mt_allocator.h:#include <bits/gthr.h> ./ext/rope:# include <bits/gthr.h> ./ext/rope:#error __GTHREAD_MUTEX_INIT or __GTHREAD_MUTEX_INIT_FUNCTION should be defined by gthr.h abstraction layer, report problem to libstdc++@gcc.gnu.org. ./alphaev56-dec-osf5.1/bits/c++io.h:#include <bits/gthr.h>
And none of these headers is included by <utility>.
But as soon as you use any I/O headers, the file gets included via "c++io.h" which is included by <iosfwd>. :-(
What a mess!!!
Indeed. I'll ask about this on the libstdc++ list. jon -- "Capitalism is the extraordinary belief that the nastiest of men, for the nastiest of reasons, will somehow work for the benefit of us all." - John Maynard Keynes

On Wed, Oct 06, 2004 at 01:11:57PM +0100, Jonathan Wakely wrote:
On Wed, Oct 06, 2004 at 12:36:58PM +0100, John Maddock wrote:
#ifdef __GLIBCXX__ // gcc 3.4 and greater: # ifdef _GLIBCXX_HAVE_GTHR_DEFAULT // // If the std lib has thread support turned on, then turn it on in Boost // as well. We do this because some gcc-3.4 std lib headers define _REENTANT // while others do not... // # define BOOST_HAS_THREADS # else # define BOOST_DISABLE_THREADS # endif #endif
John, this comment (which is in the current version in CVS) is misleading, and IMHO the whole thing is redundant.
If *any* 3.4 libstdc++ header is included and _GLIBCXX_HAVE_GTHR_DEFAULT is defined then gthr-default.h will be included and therefore _REENTRANT will be defined, and therefore BOOST_HAS_THREADS will be defined anyway by boost/config/suffix.hpp (this is the case for GCC configured for MT support.)
If _GLIBCXX_HAVE_GTHR_DEFAULT is not defined then gthr-default.h will not be included, and _REENTRANT will not be defined, and BOOST_DISABLE_THREADS will be defined by boost/config/suffix.hpp (this is the case for GCC configured with no support for MT.)
I don't think that bit of preprocessor code changes anything (but I might be wrong again)
For the record, what I wrote above is complete nonsense. Markus noted that not all libstdc++ headers include gthr.h and so won't necessarily get _REENTRANT defined, in particular <utility> doesn't include gthr.h. All libstdc++ headers do, however, include <bits/c++config.h> which defines _GLIBCXX_HAVE_GTHR_DEFAULT, so John's current checks in boost/config/stdlib/libstdcpp3.hpp would seem to be the best choice, and the comment *is* valid. My sincere apologies for confusing the issue even further! jon -- "That which needs to be proved cannot be worth much." - Nietzsche

John Maddock wrote:
Attached is the output of "gcc -ansi -dM". I hope it contains enough information to answer your questions. Note also that _REENTRANT is not defined here, therefore its source must be somewhere outside of gcc.
John, I attached a diffent patch for the file to this mail which fixes the problem. First of all, the platform in question is Tru64 (not HP-UX). Next, when the file is included by the compiler, _GLIBCPP_HAVE_GTHR_DEFAULT is _not_ defined. Therefore I changed the check to __osf__ && !_REENTRANT to just unconditionally define _REENTRANT on Tru64. If the patch is ok for you, please go ahead and commit it or just tell me and I will commit it myself. Thanks, Markus Index: libstdcpp3.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/config/stdlib/libstdcpp3.hpp,v retrieving revision 1.9 diff -u -r1.9 libstdcpp3.hpp --- libstdcpp3.hpp 30 Jun 2004 10:17:00 -0000 1.9 +++ libstdcpp3.hpp 6 Oct 2004 12:45:54 -0000 @@ -22,6 +22,12 @@ # define BOOST_NO_STD_WSTREAMBUF #endif +#if defined(__osf__) && !defined(_REENTRANT) +// GCC 3.4 on Tru64 forces the definition of _REENTRANT when any std lib header +// file is included, therefore for consistency we define it here as well. +# define _REENTRANT +#endif + #ifdef __GLIBCXX__ // gcc 3.4 and greater: # ifdef _GLIBCXX_HAVE_GTHR_DEFAULT // @@ -43,5 +49,3 @@ // support is useless. # undef BOOST_HAS_LONG_LONG #endif - -

On Wed, Oct 06, 2004 at 02:51:49PM +0200, Markus Sch?pflin wrote:
John Maddock wrote:
Attached is the output of "gcc -ansi -dM". I hope it contains enough information to answer your questions. Note also that _REENTRANT is not defined here, therefore its source must be somewhere outside of gcc.
John, I attached a diffent patch for the file to this mail which fixes the problem. First of all, the platform in question is Tru64 (not HP-UX).
Next, when the file is included by the compiler, _GLIBCPP_HAVE_GTHR_DEFAULT ^^ This should be _GLIBCXX_... not _GLIBCPP_...
Without that check you will define _REENTRANT even when GCC was configured with --disable-threads (or its equivalents such as --enable-threads=single), which would be even worse than the current state. At least the current config headers can tell whether GCC 3.4 _supports_ threads, it just can't tell whether it's _using_ threads. Since this issue only affects GCC 3.4 (previous versions did NOT define _REENTRANT unconditionally - which was a problem for OSF) if the check is for CXX not CPP then it automatically excludes previous (working) versions, as desired.
is _not_ defined. Therefore I changed the check to __osf__ && !_REENTRANT to just unconditionally define _REENTRANT on Tru64.
I still don't know why it isn't defined by the libstdc++ headers in that particular case, but is in the config_test. I wish they'd just fix this in GCC :-( jon -- "Programming is one of the most difficult branches of applied mathematics; the poorer mathematicians had better remain pure mathematicians." - Edsger Dijkstra

Jonathan Wakely wrote:
On Wed, Oct 06, 2004 at 02:51:49PM +0200, Markus Sch?pflin wrote:
John, I attached a diffent patch for the file to this mail which fixes the problem. First of all, the platform in question is Tru64 (not HP-UX).
Next, when the file is included by the compiler, _GLIBCPP_HAVE_GTHR_DEFAULT ^^ This should be _GLIBCXX_... not _GLIBCPP_...
Attached is a new patch. Hope this one is better. It now also checks against _GLIBCXX_HAVE_GTHR_DEFAULT which seems to work ok.
Without that check you will define _REENTRANT even when GCC was configured with --disable-threads (or its equivalents such as --enable-threads=single), which would be even worse than the current state. At least the current config headers can tell whether GCC 3.4 _supports_ threads, it just can't tell whether it's _using_ threads.
Since this issue only affects GCC 3.4 (previous versions did NOT define _REENTRANT unconditionally - which was a problem for OSF) if the check is for CXX not CPP then it automatically excludes previous (working) versions, as desired.
is _not_ defined. Therefore I changed the check to __osf__ && !_REENTRANT to just unconditionally define _REENTRANT on Tru64.
I still don't know why it isn't defined by the libstdc++ headers in that particular case, but is in the config_test.
Maybe I'll find some time tomorrow to track this down.
I wish they'd just fix this in GCC :-(
Agreed. Markus Index: libstdcpp3.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/config/stdlib/libstdcpp3.hpp,v retrieving revision 1.9 diff -u -r1.9 libstdcpp3.hpp --- libstdcpp3.hpp 30 Jun 2004 10:17:00 -0000 1.9 +++ libstdcpp3.hpp 6 Oct 2004 15:02:34 -0000 @@ -22,6 +22,12 @@ # define BOOST_NO_STD_WSTREAMBUF #endif +#if defined(__osf__) && !defined(_REENTRANT) && defined(_GLIBCXX_HAVE_GTHR_DEFAULT) +// GCC 3.4 on Tru64 forces the definition of _REENTRANT when any std lib header +// file is included, therefore for consistency we define it here as well. +# define _REENTRANT +#endif + #ifdef __GLIBCXX__ // gcc 3.4 and greater: # ifdef _GLIBCXX_HAVE_GTHR_DEFAULT // @@ -43,5 +49,3 @@ // support is useless. # undef BOOST_HAS_LONG_LONG #endif - -

John, I attached a diffent patch for the file to this mail which fixes the problem. First of all, the platform in question is Tru64 (not HP-UX).
Next, when the file is included by the compiler, _GLIBCPP_HAVE_GTHR_DEFAULT ^^ This should be _GLIBCXX_... not _GLIBCPP_...
Attached is a new patch. Hope this one is better. It now also checks against _GLIBCXX_HAVE_GTHR_DEFAULT which seems to work ok.
If that fixes the problem, go for it, John.

On Tue, Oct 05, 2004 at 04:06:44PM +0100, John Maddock wrote:
When compiling the smart pointer tests with gcc 3.4.2 on Tru64, two tests fail with an error message. (See http://tinyurl.com/4jngu )
As far as I can see, the shared pointer implementation at some point includes the "pthread.h" system header file but gcc on Tru64 requires that -pthread must be specified on the command line when including this header file.
When running this test with gcc 3.4.2 on Linux the file "pthread.h" is also included but gcc doesn't require the addition of -pthread in the command line on this platform.
This leads to the question whether it is ok to include "pthread.h" without specifying -pthread on the command line. Does anyone know an answer to this?
I think on some platforms <pthread.h> doesn't compile unless _REENTRANT or some similar compiler-specific magic symbol is defined: in other words it's an assert that the compiler is indeed in thread safe mode.
IIUC "some platforms" applies to Tru64 and nothing else.
It looks to me as though BOOST_HAS_THREADS is getting set unconditionally for gcc on this platform, and presumably we should only set it when _REENTRANT is defined
See GCC PR 11953 - _REENTRANT gets defined unconditionally for GCC 3.4 on all platforms when configured to use pthreads, and therefore BOOST_HAS_THREADS also gets defined unconditioanlly. That's what PR 11953 is about :) GCC was changed to unconditionally define _REENTRANT precisely because Tru64 requires it before including pthread.h (and libstdc++ wants to include pthread.h). I might update the PR to say that this causes problems even on Tru64, where it was supposed to help (although the response will be to tell me again that Boost should never have used _REENTRANT anyway)
(I'm assuming that's the symbol that gets defined when the -thread option is used - can you check?).
Yes, assuming I'm looking at the right file, gcc/config/alpha/osf.h: #undef CPP_SUBTARGET_SPEC #define CPP_SUBTARGET_SPEC \ "%{pthread|threads:-D_REENTRANT} %{threads:-D_PTHREAD_USE_D4}" /* Under OSF4, -p and -pg require -lprof1, and -lprof1 requires -lpdf. */ #define LIB_SPEC \ "%{p|pg:-lprof1%{pthread|threads:_r} -lpdf} %{a:-lprof2} \ %{threads: -lpthreads} %{pthread|threads: -lpthread -lmach -lexc} -lc"
Hold on... checked the output from config_info and looks as though _REENTRANT *is* defined, so I'm mystified.
That's because the config_info test includes <iostream> which indirectly defines _REENTRANT and includes pthread.h Sooooooo .... why is the compiler saying Markus needs to define it if it is defined? (sorry John, I see what you were getting at now :) Markus, could you send me the pthread.h header from GCC? That's the one that GCC produced by running fixincludes on the system pthread.h: /usr/opt/gcc-3.4.2/bin/../lib/gcc/alphaev56-dec-osf5.1/3.4.2/include/pthread.h Or at least show what's around line 339?
I also note that the platform is detected as "generic unix". Do you know what macros gcc defines to identify this platform?
Again, from gcc/config/alpha/osf.h: #define TARGET_OS_CPP_BUILTINS() \ do { \ builtin_define_std ("unix"); \ builtin_define_std ("SYSTYPE_BSD"); \ builtin_define ("_SYSTYPE_BSD"); \ builtin_define ("__osf__"); \ builtin_define ("__digital__"); \ builtin_define ("__arch64__"); \ builtin_define ("_LONGLONG"); \ builtin_define ("__PRAGMA_EXTERN_PREFIX"); \ builtin_assert ("system=unix"); \ builtin_assert ("system=xpg4"); \ /* Tru64 UNIX V5 has a 16 byte long \ double type and requires __X_FLOAT \ to be defined for <math.h>. */ \ if (LONG_DOUBLE_TYPE_SIZE == 128) \ builtin_define ("__X_FLOAT"); \ \ /* Tru64 UNIX V4/V5 provide several ISO C94 \ features protected by the corresponding \ __STDC_VERSION__ macro. libstdc++ v3 \ needs them as well. */ \ if (c_dialect_cxx ()) \ builtin_define ("__STDC_VERSION__=199409L"); \ } while (0) jon -- http://c2.com/cgi/wiki?NeverExplain

Jonathan Wakely wrote:
Markus, could you send me the pthread.h header from GCC? That's the one that GCC produced by running fixincludes on the system pthread.h: /usr/opt/gcc-3.4.2/bin/../lib/gcc/alphaev56-dec-osf5.1/3.4.2/include/pthread.h
Or at least show what's around line 339?
Sent to you privately. Markus

On Tue, Oct 05, 2004 at 03:05:13PM +0200, Markus Sch?pflin wrote:
When compiling the smart pointer tests with gcc 3.4.2 on Tru64, two tests fail with an error message. (See http://tinyurl.com/4jngu )
As far as I can see, the shared pointer implementation at some point includes the "pthread.h" system header file but gcc on Tru64 requires that -pthread must be specified on the command line when including this header file.
Markus, I believe what you're seeing is the problem that prompted the GCC developers to unconditionally define _REENTRANT even when -pthread is not given (and which breaks Boost for GCC 3.4), see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11953 Technically, Tru64's pthread.h doesn't require -pthread, it requires _REENTRANT. -pthread on Tru64 defines _REENTRANT, but if you want to include the file without having to use -pthread then just ensure _REENTRANT is defined. The solution that libstdc++ uses is to ensure _REENTRANT is defined before including pthread.h. That allows the file to be included without having to link to the pthread libs etc. (I think). Now if only they'd fix libstdc++ so _REENTRANT only gets defined on OSF, not on Linux and other platforms that don't require it! jon
included but gcc doesn't require the addition of -pthread in the command line on this platform.
This leads to the question whether it is ok to include "pthread.h" without specifying -pthread on the command line. Does anyone know an answer to this?
-- "Anybody who hates dogs and loves whiskey can't be all bad." - W.C. Fields

Markus, I believe what you're seeing is the problem that prompted the GCC developers to unconditionally define _REENTRANT even when -pthread is not given (and which breaks Boost for GCC 3.4), see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11953
That's what I thought, but http://tinyurl.com/3lyr8 suggests that _REENTRANT *is* defined, even without -pthread (unless this is an artifact of including <iostream>). Confused yours, John.

On Tue, Oct 05, 2004 at 04:28:46PM +0100, John Maddock wrote:
Markus, I believe what you're seeing is the problem that prompted the GCC developers to unconditionally define _REENTRANT even when -pthread is not given (and which breaks Boost for GCC 3.4), see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11953
That's what I thought, but http://tinyurl.com/3lyr8 suggests that _REENTRANT *is* defined, even without -pthread (unless this is an artifact of including <iostream>).
<iostream> includes <ostream> which includes <ios> which includes <iosfwd> which includes $platform/bits/c++io.h which includes gthr.h which includes gthr-default.h which defines _REENTRANT to 1. Solution: define _REENTRANT before including anything, or include a libstdc++ header (which will define _REENTRANT and include pthread.h) jon -- A man needs a mistress, just to break the monogamy.

Jonathan Wakely wrote:
On Tue, Oct 05, 2004 at 04:28:46PM +0100, John Maddock wrote:
Markus, I believe what you're seeing is the problem that prompted the GCC developers to unconditionally define _REENTRANT even when -pthread is not given (and which breaks Boost for GCC 3.4), see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11953
That's what I thought, but http://tinyurl.com/3lyr8 suggests that _REENTRANT *is* defined, even without -pthread (unless this is an artifact of including <iostream>).
<iostream> includes <ostream> which includes <ios> which includes <iosfwd> which includes $platform/bits/c++io.h which includes gthr.h which includes gthr-default.h which defines _REENTRANT to 1.
That's what I also discovered.
Solution: define _REENTRANT before including anything, or include a libstdc++ header (which will define _REENTRANT and include pthread.h)
The native compiler (toolset tru64cxx65) doesn't define _REENTRANT and things seem to work out correctly. GCC's include files OTOH unconditionally define _REENTRANT before including "pthread.h" which forces boost to also include "pthread.h", if I understand things correctly. But reentrant is not defined at the point where "pthread.h" is included which leads to the problem described. I think I'm missing something here. Markus

On Tue, Oct 05, 2004 at 06:23:46PM +0200, Markus Sch?pflin wrote:
Jonathan Wakely wrote:
On Tue, Oct 05, 2004 at 04:28:46PM +0100, John Maddock wrote:
Markus, I believe what you're seeing is the problem that prompted the GCC developers to unconditionally define _REENTRANT even when -pthread is not given (and which breaks Boost for GCC 3.4), see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11953
That's what I thought, but http://tinyurl.com/3lyr8 suggests that _REENTRANT *is* defined, even without -pthread (unless this is an artifact of including <iostream>).
<iostream> includes <ostream> which includes <ios> which includes <iosfwd> which includes $platform/bits/c++io.h which includes gthr.h which includes gthr-default.h which defines _REENTRANT to 1.
That's what I also discovered.
Solution: define _REENTRANT before including anything, or include a libstdc++ header (which will define _REENTRANT and include pthread.h)
The native compiler (toolset tru64cxx65) doesn't define _REENTRANT and things seem to work out correctly.
If you use the tru64cxx65 equivalent of -pthread then I bet it _does_ define _REENTRANT. The problem is that GCC was changed so that _REENTRANT is defined whether or not -pthread is used.
GCC's include files OTOH unconditionally define _REENTRANT before including "pthread.h" which forces boost to also include "pthread.h", if I understand things correctly.
Near enough, yeah.
But reentrant is not defined at the point where "pthread.h" is included which leads to the problem described.
Why not though, that's the question. Since <boost/config.h> is included first by shared_ptr.hpp, that should include <string> (or any other libstdc++ header) which should define _REENTRANT and therefore it should be set when we come to pthread.h If you want to, run the test with the GCC flag -save-temps and send me the preprocessed .ii file, and I'll get medieval on it. jon -- "Hell is other people's code." - Me, after a day spent refactoring particularly smelly garbage.

Jonathan Wakely wrote:
On Tue, Oct 05, 2004 at 06:23:46PM +0200, Markus Schöpflin wrote:
The native compiler (toolset tru64cxx65) doesn't define _REENTRANT and things seem to work out correctly.
If you use the tru64cxx65 equivalent of -pthread then I bet it _does_ define _REENTRANT. The problem is that GCC was changed so that _REENTRANT is defined whether or not -pthread is used.
Yep, you're right. -pthread toggles the definition of _REENTRANT on cxx. Interestingly it does this also with gcc when you look at the output of the predefined macros of the compiler.
GCC's include files OTOH unconditionally define _REENTRANT before including "pthread.h" which forces boost to also include "pthread.h", if I understand things correctly.
Near enough, yeah.
But reentrant is not defined at the point where "pthread.h" is included which leads to the problem described.
Why not though, that's the question.
Since <boost/config.h> is included first by shared_ptr.hpp, that should include <string> (or any other libstdc++ header) which should define _REENTRANT and therefore it should be set when we come to pthread.h
If you want to, run the test with the GCC flag -save-temps and send me the preprocessed .ii file, and I'll get medieval on it.
Will do in private mail. Thanks in advance. Markus
participants (5)
-
Christoph Ludwig
-
John Maddock
-
Jonathan Wakely
-
Markus Schöpflin
-
Peter Dimov