Re: [boost] [Boost-users] Boost threads + MSVSC + /Za + client code

Hi, Any takers? The workaround I've found for the problem below is to #define _MSC_EXTENSIONS before including any boost thread headers. It /appears/ that this is only necessary when separately compiling boost threads. Sorry for the cross-post.
With Visual C++, I can't seem to determine why if I simply include boost/threads/once.hpp, I need to enable language extensions for that translation unit. I'm going to dig into this further today but I would appreciate if someone has figured out a solution short of allowing language extensions. I can understand requiring it for building boost threads (as windows.h seems to have some extended syntax) but I'm not sure of the logic behind requiring client code to use it as well.
Thanks! Sohail

"Sohail Somani" <s.somani@fincad.com> writes:
Any takers? The workaround I've found for the problem below is to #define _MSC_EXTENSIONS before including any boost thread headers. It /appears/ that this is only necessary when separately compiling boost threads. Sorry for the cross-post.
With Visual C++, I can't seem to determine why if I simply include boost/threads/once.hpp, I need to enable language extensions for that translation unit. I'm going to dig into this further today but I would appreciate if someone has figured out a solution short of allowing language extensions. I can understand requiring it for building boost threads (as windows.h seems to have some extended syntax) but I'm not sure of the logic behind requiring client code to use it as well.
The problem is a combination of things. boost/config/compiler/visualc.hpp defines BOOST_DISABLE_WIN32 if extensions are disabled, presumably since windows.h relies on Microsoft compiler extensions. boost/config/suffix.hpp then defines BOOST_DISABLE_THREADS if BOOST_DISABLE_WIN32 is defined and BOOST_HAS_PTHREADS is not; the implication is that if you can't use the Windows headers, then you can't use the Windows thread API, so if we haven't got pthread-win32 configured, you can't use Boost threads. I am not sure what we can do about this. One issue is that currently the thread lib requires windows.h, and therefore compiler extensions, when the library sources are built. I'm not sure whether it is safe to link something compiled with extensions on against something compiled with extensions off --- is the ABI the same? If it *is* safe, then we should remove this define from boost/config/suffix.hpp, since the boost thread headers don't explicitly include windows.h. OTOH, someone put the restriction there for a reason, and I wouldn't want to remove it without careful thought. Anthony -- Anthony Williams Software Developer Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk

Anthony Williams wrote:
"Sohail Somani" <s.somani@fincad.com> writes:
Any takers? The workaround I've found for the problem below is to #define _MSC_EXTENSIONS before including any boost thread headers. It /appears/ that this is only necessary when separately compiling boost threads. Sorry for the cross-post.
With Visual C++, I can't seem to determine why if I simply include boost/threads/once.hpp, I need to enable language extensions for that translation unit. I'm going to dig into this further today but I would appreciate if someone has figured out a solution short of allowing language extensions. I can understand requiring it for building boost threads (as windows.h seems to have some extended syntax) but I'm not sure of the logic behind requiring client code to use it as well.
The problem is a combination of things. boost/config/compiler/visualc.hpp defines BOOST_DISABLE_WIN32 if extensions are disabled, presumably since windows.h relies on Microsoft compiler extensions. boost/config/suffix.hpp then defines BOOST_DISABLE_THREADS if BOOST_DISABLE_WIN32 is defined and BOOST_HAS_PTHREADS is not; the implication is that if you can't use the Windows headers, then you can't use the Windows thread API, so if we haven't got pthread-win32 configured, you can't use Boost threads.
I am not sure what we can do about this. One issue is that currently the thread lib requires windows.h, and therefore compiler extensions, when the library sources are built. I'm not sure whether it is safe to link something compiled with extensions on against something compiled with extensions off --- is the ABI the same? If it *is* safe, then we should remove this define from boost/config/suffix.hpp, since the boost thread headers don't explicitly include windows.h.
OTOH, someone put the restriction there for a reason, and I wouldn't want to remove it without careful thought.
Your analysis is correct. This may prove to be a tricky one: I think we can safely link to the thread lib when building with /Za, but I suspect that there are other libraries that depend on BOOST_HAS_THREADS as well: in fact a quick search through the headers showed rather a lot of uses, some relate to use of Boost.Threads, but many don't. I guess we could invent a new macro BOOST_HAS_THREAD_LIB or something, but then to be consistent, we would have to change some but not all uses of BOOST_HAS_THREADS in other libraries to this new macro. Tricky to get it all right. Also, haven't some of the Boost.Thread components become header only now? Will these still work with /Za? Apologies for raising more questions than answers! John.

"John Maddock" <john@johnmaddock.co.uk> writes:
This may prove to be a tricky one: I think we can safely link to the thread lib when building with /Za, but I suspect that there are other libraries that depend on BOOST_HAS_THREADS as well: in fact a quick search through the headers showed rather a lot of uses, some relate to use of Boost.Threads, but many don't.
I guess we could invent a new macro BOOST_HAS_THREAD_LIB or something, but then to be consistent, we would have to change some but not all uses of BOOST_HAS_THREADS in other libraries to this new macro. Tricky to get it all right.
Yes, especially without an automated test for this scenario. Something to leave for 1.35?
Also, haven't some of the Boost.Thread components become header only now?
Yes.
Will these still work with /Za?
Yes. That's the intention, anyway. Anthony -- Anthony Williams Software Developer Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk

Anthony Williams wrote:
The problem is a combination of things. boost/config/compiler/visualc.hpp defines BOOST_DISABLE_WIN32 if extensions are disabled, presumably since windows.h relies on Microsoft compiler extensions. boost/config/suffix.hpp then defines BOOST_DISABLE_THREADS if BOOST_DISABLE_WIN32 is defined and BOOST_HAS_PTHREADS is not; the implication is that if you can't use the Windows headers, then you can't use the Windows thread API, so if we haven't got pthread-win32 configured, you can't use Boost threads.
This is incorrect for two reasons. One, you don't have to include a windows header in order to use Boost.Threads. Two, the fact that a translation unit is built with /Za doesn't automatically make this unit single threaded; libraries that depend on BOOST_DISABLE_THREADS (or on the absence of BOOST_HAS_THREADS) to disable their internal synchronization will break. It's possible to spawn threads without including a windows header.

"Peter Dimov" <pdimov@mmltd.net> writes:
Anthony Williams wrote:
The problem is a combination of things. boost/config/compiler/visualc.hpp defines BOOST_DISABLE_WIN32 if extensions are disabled, presumably since windows.h relies on Microsoft compiler extensions. boost/config/suffix.hpp then defines BOOST_DISABLE_THREADS if BOOST_DISABLE_WIN32 is defined and BOOST_HAS_PTHREADS is not; the implication is that if you can't use the Windows headers, then you can't use the Windows thread API, so if we haven't got pthread-win32 configured, you can't use Boost threads.
This is incorrect for two reasons. One, you don't have to include a windows header in order to use Boost.Threads. Two, the fact that a translation unit is built with /Za doesn't automatically make this unit single threaded; libraries that depend on BOOST_DISABLE_THREADS (or on the absence of BOOST_HAS_THREADS) to disable their internal synchronization will break. It's possible to spawn threads without including a windows header.
Agreed; I was just highlighting the status quo. I find it strange that BOOST_DISABLE_THREADS is defined under these conditions, and would rather it wasn't. However, someone put the checks in there, and must have done for a reason, so just changing it would seem like a bad idea, unless we have suitable tests to verify that it's OK. Looking at the history, this check has been there since John Maddock added it in May 2002 for release 1.28. Anthony -- Anthony Williams Software Developer Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk

Anthony Williams wrote:
"Peter Dimov" <pdimov@mmltd.net> writes:
Anthony Williams wrote:
The problem is a combination of things. boost/config/compiler/visualc.hpp defines BOOST_DISABLE_WIN32 if extensions are disabled, presumably since windows.h relies on Microsoft compiler extensions. boost/config/suffix.hpp then defines BOOST_DISABLE_THREADS if BOOST_DISABLE_WIN32 is defined and BOOST_HAS_PTHREADS is not; the implication is that if you can't use the Windows headers, then you can't use the Windows thread API, so if we haven't got pthread-win32 configured, you can't use Boost threads.
This is incorrect for two reasons. One, you don't have to include a windows header in order to use Boost.Threads. Two, the fact that a translation unit is built with /Za doesn't automatically make this unit single threaded; libraries that depend on BOOST_DISABLE_THREADS (or on the absence of BOOST_HAS_THREADS) to disable their internal synchronization will break. It's possible to spawn threads without including a windows header.
Agreed; I was just highlighting the status quo. I find it strange that BOOST_DISABLE_THREADS is defined under these conditions, and would rather it wasn't.
Thinking about it a bit more, there is a third reason that Boost.Config shouldn't be doing that. BOOST_DISABLE_THREADS is a user macro, and the config system shouldn't be touching it. The easiest solution is to ignore Boost.Config until the meanings of _HAS_THREADS and _DISABLE_THREADS are sorted out and check everything at the library level.

Anthony Williams wrote:
I am not sure what we can do about this. One issue is that currently the thread lib requires windows.h, and therefore compiler extensions, when the library sources are built. I'm not sure whether it is safe to link something compiled with extensions on against something compiled with extensions off --- is the ABI the same?
I am pretty much sure it is. Otherwise it would be impossible to link a library, which even might be produced by a compiler of a different laguage.
If it *is* safe, then we should remove this define from boost/config/suffix.hpp, since the boost thread headers don't explicitly include windows.h.
Hmm, true for the current version, but if we go header only in future?
OTOH, someone put the restriction there for a reason, and I wouldn't want to remove it without careful thought.
I always thought it was a bad idea for the Boost.Thread to explicitly depend on these macros when invoked from client builds. If you look into my platform split of the thread_rewrite branch you will see, that I have tried to not rely on these, and as it turns out now this is a good thing. (Altough it does not go yet all the way, just pointing the direction.) The client code might be interested which threading API is available _if_ it is going to make use of it. If Boost.Thread is being used the client code needs not know (and should be able to compile without language extensions). Another issue is the semantics of BOOST_HAS_THREADS: Does it mean 1) No OS threading API available or 2) No threading at all ? I currently see it as 1). You still should be able to use Boost.Thread. Then when client code defines: BOOST_DISABLE_THREADS the implementation of Boost.Thread could make use of this information and replace everything that makes sense with stubs. It does not make sense to stub out the thread launching API, but it makes sense for the locking API. Thread launching should give a compile error in this case. This would allow library users to write MT aware library code without #idefing when used in a single thread context. All this does not help much in the current implementation, and I would not attempt to change any of these short before release. But we definitely should do it for the next release! Sorry for my whining, but I have to reiterate: We should _not_ try to do as much as possible header only. This issue is just another bullet on my list why we should not. I agree there are lot of things which require header only, but we should try to do as much as possible using the library mechanism. Roland
participants (5)
-
Anthony Williams
-
John Maddock
-
Peter Dimov
-
Roland Schwarz
-
Sohail Somani