1.49 header order conflicts on Windows

Consider this following simple app: #include <boost/thread/thread.hpp> #include <boost/asio.hpp> #include <boost/thread/recursive_mutex.hpp> int main() { return 0; } If you try to build that on Windows, you receive the following error: In file included from c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/recursive_mutex.hpp:14:0, from c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/recursive_mutex.hpp:14, from build.cpp:3: c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/basic_recursive_mutex.hpp: In member function 'void boost::detail::basic_recursive_mutex_impl<underlying_mutex_type>::lock()': c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/basic_recursive_mutex.hpp:52:21: error: '_InterlockedExchange' is not a member of 'boost::detail' c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/basic_recursive_mutex.hpp: In member function 'void boost::detail::basic_recursive_mutex_impl<underlying_mutex_type>::unlock()': c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/basic_recursive_mutex.hpp:71:21: error: '_InterlockedExchange' is not a member of 'boost::detail' c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/basic_recursive_mutex.hpp: In member function 'bool boost::detail::basic_recursive_mutex_impl<underlying_mutex_type>::try_basic_lock(long int)': c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/basic_recursive_mutex.hpp:91:21: error: '_InterlockedExchange' is not a member of 'boost::detail' c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/basic_recursive_mutex.hpp: In member function 'bool boost::detail::basic_recursive_mutex_impl<underlying_mutex_type>::try_timed_lock(long int, const boost::system_time&)': c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/basic_recursive_mutex.hpp:102:21: error: '_InterlockedExchange' is not a member of 'boost::detail' If asio.hpp is moved ahead of the thread headers, the error goes away. We've been trying to dictate #include order to work around this problem, but it keeps cropping up.

On Wed, Jun 13, 2012 at 07:03:01PM +0000, Davidson, Josh wrote:
Consider this following simple app:
#include <boost/thread/thread.hpp> #include <boost/asio.hpp> #include <boost/thread/recursive_mutex.hpp>
If asio.hpp is moved ahead of the thread headers, the error goes away. We've been trying to dictate #include order to work around this problem, but it keeps cropping up.
Asio is "friendly" enough to define WIN32_LEAN_AND_MEAN for you, which pretty much breaks any other consumer of Windows.h. Consider setting BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN project-wide and whine at whoever made this deranged behaviour the default. Also beware of its sibling BOOST_ASIO_NO_NOMINMAX, which inhibits the definition of NOMINMAX. http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio/using.html#boost_as... -- Lars Viklund | zao@acc.umu.se

On Wed, Jun 13, 2012 at 11:34:20PM +0200, Lars Viklund wrote:
On Wed, Jun 13, 2012 at 07:03:01PM +0000, Davidson, Josh wrote:
Consider this following simple app:
#include <boost/thread/thread.hpp> #include <boost/asio.hpp> #include <boost/thread/recursive_mutex.hpp>
If asio.hpp is moved ahead of the thread headers, the error goes away. We've been trying to dictate #include order to work around this problem, but it keeps cropping up.
Asio is "friendly" enough to define WIN32_LEAN_AND_MEAN for you, which pretty much breaks any other consumer of Windows.h.
Consider setting BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN project-wide and whine at whoever made this deranged behaviour the default.
Disregard the above, I misunderstood your "ahead" there. Which mingw is this exactly? There's a lot of them out there; original mingw, mingw-w64 personals/automatic, DGN, TDM, etc. There might be some header providing the intrinsics that gets automatically included with MSVC but not Mingw, which Asio happens to pull in through some other header. -- Lars Viklund | zao@acc.umu.se

I haven't a windows machine at hand. Please could you get the result of the preprocessor and see what is happening with the detail/interlocked.hpp file where boost::detail::InterlockedExchange should be defined? The preprocessor output is over 4MB, but here is the snippet for interlocked.hpp:
# 1 "c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/config/abi_suffix.hpp" 1 3 # 181 "c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/exceptions.hpp" 2 3 # 17 "c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/thread_primitives.hpp" 2 3 # 1 "c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/detail/interlocked.hpp" 1 3 # 120 "c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/detail/interlocked.hpp" 3 namespace boost { namespace detail { extern "C" long InterlockedIncrement( long volatile * ); extern "C" long InterlockedDecrement( long volatile * ); extern "C" long InterlockedCompareExchange( long volatile *, long, long ); extern "C" long InterlockedExchange( long volatile *, long ); extern "C" long InterlockedExchangeAdd( long volatile *, long ); extern "C" void* InterlockedCompareExchangePointer( void* volatile *, void*, void* ); extern "C" void* InterlockedExchangePointer( void* volatile *, void* ); } } # 18 "c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/thread_primitives.hpp" 2 3 # 91 "c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/thread_primitives.hpp" 3
Which mingw is this exactly? There's a lot of them out there; original mingw, mingw-w64 personals/automatic, DGN, TDM, etc.
Mingw-w64 (non-personal): c:\TEMP>g++ -v Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/x86_64-w64-mingw32/4.5.3/lto-wrapper.exe Target: x86_64-w64-mingw32 Configured with: ../../../build/gcc/src/configure --target=x86_64-w64-mingw32 --prefix=/c/buildbot/mingw-w64/mingw32/mingw-x86-x86_64/build/build/root --with-sysroot=/c/buildbot/mingw-w64/mingw32/mingw-x86-x86_64/build/build/root --enable-languages=all,obj-c++ --enable-fully-dynamic-string --disable-multilib Thread model: win32 gcc version 4.5.3 20110207 (prerelease) (GCC) Behavior is the same for other mingw-w64 releases I've tried: c:\TEMP>c:\MinGW.47\bin\g++ -v Using built-in specs. COLLECT_GCC=c:\MinGW.47\bin\g++ COLLECT_LTO_WRAPPER=c:/mingw.47/bin/../libexec/gcc/x86_64-w64-mingw32/4.7.0/lto-wrapper.exe Target: x86_64-w64-mingw32 Configured with: ../../../build/gcc/src/configure --target=x86_64-w64-mingw32 --prefix=/c/bb/vista64-mingw32/mingw-x86-x86_64/build/build/root --with-sysroot=/c/bb/vista64-mingw32/mingw-x86-x86_64/build/build/root --enable-languages=all,obj-c++ --enable-fully-dynamic-string --disable-multilib Thread model: win32 gcc version 4.7.0 20111220 (experimental) (GCC) c:\TEMP>"c:\MinGW.dragon\bin\g++.exe" -v Using built-in specs. COLLECT_GCC=c:\MinGW.dragon\bin\g++.exe COLLECT_LTO_WRAPPER=c:/mingw.dragon/bin/../libexec/gcc/x86_64-w64-mingw32/4.6.3/lto-wrapper.exe Target: x86_64-w64-mingw32 Configured with: /home/drangon/work/mingw-w64-dgn/source/gcc/configure --host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --disable-nls --enable-languages=c,c++,objc,obj-c++ --with-gmp=/home/drangon/work/mingw-w64-dgn/build/for_target --enable-twoprocess --disable-libstdcxx-pch --disable-win32-registry --prefix=/home/drangon/work/mingw-w64-dgn/target --with-sysroot=/home/drangon/work/mingw-w64-dgn/target Thread model: win32 gcc version 4.6.3 20120127 (prerelease) (GCC)

Le 14/06/12 00:32, Davidson, Josh a écrit :
I haven't a windows machine at hand. Please could you get the result of the preprocessor and see what is happening with the detail/interlocked.hpp file where boost::detail::InterlockedExchange should be defined? The preprocessor output is over 4MB, but here is the snippet for interlocked.hpp:
# 1 "c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/config/abi_suffix.hpp" 1 3 # 181 "c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/exceptions.hpp" 2 3 # 17 "c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/thread_primitives.hpp" 2 3 # 1 "c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/detail/interlocked.hpp" 1 3 # 120 "c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/detail/interlocked.hpp" 3 namespace boost {
namespace detail {
extern "C" long InterlockedIncrement( long volatile * ); extern "C" long InterlockedDecrement( long volatile * ); extern "C" long InterlockedCompareExchange( long volatile *, long, long ); extern "C" long InterlockedExchange( long volatile *, long ); extern "C" long InterlockedExchangeAdd( long volatile *, long );
extern "C" void* InterlockedCompareExchangePointer( void* volatile *, void*, void* ); extern "C" void* InterlockedExchangePointer( void* volatile *, void* );
}
} # 18 "c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/thread_primitives.hpp" 2 3 # 91 "c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/thread_primitives.hpp" 3
Could you add also the lines concerning the error? Vicente

Le 14/06/12 00:32, Davidson, Josh a écrit :
I haven't a windows machine at hand. Please could you get the result of the preprocessor and see what is happening with the detail/interlocked.hpp file where boost::detail::InterlockedExchange should be defined? The preprocessor output is over 4MB, but here is the snippet for interlocked.hpp: Could you also send the command line you use to get this error?
Vicente

Right now, I'm just using: g++ build.cpp -lboost_system -lws2_32 I also tried: g++ build.cpp -DBOOST_ASIO_NO_WIN32_LEAN_AND_MEAN build.cpp -lboost_system -lws2_32 (same error) For further clarification, the following header orders work: 1: #include <boost/thread/thread.hpp> #include <boost/thread/recursive_mutex.hpp> #include <boost/asio.hpp> 2: #include <boost/asio.hpp> #include <boost/thread/thread.hpp> #include <boost/thread/recursive_mutex.hpp> This one does not: #include <boost/thread/thread.hpp> #include <boost/asio.hpp> #include <boost/thread/recursive_mutex.hpp> Here is the definition for the lock method that the compilation fails on: void lock() { long const current_thread_id=win32::GetCurrentThreadId(); if(!try_recursive_lock(current_thread_id)) { mutex.lock(); ::boost::detail::_InterlockedExchange(&locking_thread_id,current_thread_id); recursion_count=1; } } -----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Vicente J. Botet Escriba Sent: Wednesday, June 13, 2012 6:11 PM To: boost-users@lists.boost.org Subject: Re: [Boost-users] EXTERNAL: Re: 1.49 header order conflicts on Windows Le 14/06/12 00:32, Davidson, Josh a écrit :
I haven't a windows machine at hand. Please could you get the result of the preprocessor and see what is happening with the detail/interlocked.hpp file where boost::detail::InterlockedExchange should be defined? The preprocessor output is over 4MB, but here is the snippet for interlocked.hpp: Could you also send the command line you use to get this error?
Vicente _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Le 13/06/12 21:03, Davidson, Josh a écrit :
Consider this following simple app:
#include <boost/thread/thread.hpp>
#include <boost/asio.hpp>
#include <boost/thread/recursive_mutex.hpp>
int main() {
return 0;
}
If you try to build that on Windows, you receive the following error:
In file included from c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/recursive_mutex.hpp:14:0,
from c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/recursive_mutex.hpp:14,
from build.cpp:3:
c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/basic_recursive_mutex.hpp: In member function 'void boost::detail::basic_recursive_mutex_impl<underlying_mutex_type>::lock()':
c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/basic_recursive_mutex.hpp:52:21: error: '_InterlockedExchange' is not a member of 'boost::detail'
c:/mingw/lib/gcc/../../x86_64-w64-mingw32/include/boost/thread/win32/basic_recursive_mutex.hpp: In member function 'void boost::detail::basic_recursive_mutex_impl<underlying_mutex_type>::unlock()':
If asio.hpp is moved ahead of the thread headers, the error goes away. We've been trying to dictate #include order to work around this problem, but it keeps cropping up.
Hi, I haven't a windows machine at hand. Please could you get the result of the preprocessor and see what is happening with the detail/interlocked.hpp file where boost::detail::InterlockedExchange should be defined? Could you also send the command line you use to get this error? Thanks, Vicente

On Wed, Jun 13, 2012 at 07:03:01PM +0000, Davidson, Josh wrote:
Consider this following simple app:
#include <boost/thread/thread.hpp> #include <boost/asio.hpp> #include <boost/thread/recursive_mutex.hpp>
If asio.hpp is moved ahead of the thread headers, the error goes away. We've been trying to dictate #include order to work around this problem, but it keeps cropping up.
I've got an idea to the root cause here. The primitives like InterlockedExchange requires a minimum of XP/2003 support, so you need _WIN32_WINNT to be at least 0x501 in order to target a minimum OS version of XP. I believe that Asio defines _WIN32_WINNT to a sufficiently high value in order to get the OS primitives it needs, and as such, implicitly ensures that the thread code gets them too. Either Boost.Thread ought to also define this if it's not already defined, and probably error out hard with a nice message if it's not targetting a sufficiently fancy Windows version. -- Lars Viklund | zao@acc.umu.se

#include <boost/thread/thread.hpp> #include <boost/asio.hpp> //#include <boost/thread/recursive_mutex.hpp> #include <iostream> using namespace std; int main() { cout << _WIN32_WINNT << endl; return 0; } This prints: 1282 Same for this (as well as each one of those headers by themselves): //#include <boost/thread/thread.hpp> #include <boost/asio.hpp> //#include <boost/thread/recursive_mutex.hpp> #include <iostream> using namespace std; int main() { cout << _WIN32_WINNT << endl; return 0; } I'm on Windows 7 x64. -----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Lars Viklund Sent: Thursday, June 14, 2012 7:17 AM To: boost-users@lists.boost.org Subject: EXTERNAL: Re: [Boost-users] 1.49 header order conflicts on Windows On Wed, Jun 13, 2012 at 07:03:01PM +0000, Davidson, Josh wrote:
Consider this following simple app:
#include <boost/thread/thread.hpp> #include <boost/asio.hpp> #include <boost/thread/recursive_mutex.hpp>
If asio.hpp is moved ahead of the thread headers, the error goes away. We've been trying to dictate #include order to work around this problem, but it keeps cropping up.
I've got an idea to the root cause here. The primitives like InterlockedExchange requires a minimum of XP/2003 support, so you need _WIN32_WINNT to be at least 0x501 in order to target a minimum OS version of XP. I believe that Asio defines _WIN32_WINNT to a sufficiently high value in order to get the OS primitives it needs, and as such, implicitly ensures that the thread code gets them too. Either Boost.Thread ought to also define this if it's not already defined, and probably error out hard with a nice message if it's not targetting a sufficiently fancy Windows version. -- Lars Viklund | zao@acc.umu.se _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (3)
-
Davidson, Josh
-
Lars Viklund
-
Vicente J. Botet Escriba