[Thread] possible bug in Move emulation "portable interface"

I tried submitting this via Trac but for some reason it was convinced that my bug report contained spam, while refusing to tell me what part it was objecting to, and also refusing to give me a captcha or anything to convince it otherwise. Anyways: Bug 1: the Boost.Thread documentation and release history indicate that BOOST_THREAD_VERSION==3 is the default since v1.52. As far as I can tell this has never been true in any released version; the latest code still has ==2. (I found a thread in boost-devel that was debating consequences of making breaking changes by default, which I assume is why this change was not actually made; but the docs need correcting.) Bug 2: when writing code using the Boost.Thread "Portable Interface" for move support/emulation, it recommends using the BOOST_THREAD_DCL_MOVABLE_BEG macro to "avoid conflicts with Boost.Move". However regardless of C++11 or not or the BOOST_THREAD_VERSION it defines a template specialisation in a way that assumes that it is called only from "namespace boost". As this usage is unlikely for any code outside the boost library itself, I think this is a bug. namespace user { template<typename T> class test { public: BOOST_THREAD_COPYABLE_AND_MOVABLE(test) test() {} test(const test&) {} test& operator=(BOOST_COPY_ASSIGN_REF(test) o) { return *this; } test(BOOST_THREAD_RV_REF(test) o) {} test& operator=(BOOST_THREAD_RV_REF(test) o) { return *this; } }; BOOST_THREAD_DCL_MOVABLE_BEG(T) test<T> BOOST_THREAD_DCL_MOVABLE_END } The above code will not compile. It does compile if the DCL define is moved into a "namespace boost" block, but I do not regard this as an acceptable solution. Suggested fix is to explicitly specify the namespace in the macro, eg. replace "enable_move_utility_emulation" with "::boost::enable_move_utility_emulation".

On 4 Sep 2013 at 17:53, Gavin Lambert wrote:
Bug 1: the Boost.Thread documentation and release history indicate that BOOST_THREAD_VERSION==3 is the default since v1.52. As far as I can tell this has never been true in any released version; the latest code still has ==2.
That can't be true. Proposed Boost.AFIO sees BOOST_THREAD_VERSION=3 and I have preprocessor support for if BOOST_THREAD_VERSION=4 too. AFIO needs Boost v1.53 minimum, though only works with v1.54. AFIO is exclusively C++11, so I suppose it's possible Boost.Thread sets the minimum BOOST_THREAD_VERSION=3 if C++11 is on? Niall -- Currently unemployed and looking for work. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/

Le 06/09/13 17:57, Niall Douglas a écrit :
On 4 Sep 2013 at 17:53, Gavin Lambert wrote:
Bug 1: the Boost.Thread documentation and release history indicate that BOOST_THREAD_VERSION==3 is the default since v1.52. As far as I can tell this has never been true in any released version; the latest code still has ==2. That can't be true. Proposed Boost.AFIO sees BOOST_THREAD_VERSION=3 and I have preprocessor support for if BOOST_THREAD_VERSION=4 too. AFIO needs Boost v1.53 minimum, though only works with v1.54. AFIO is exclusively C++11, so I suppose it's possible Boost.Thread sets the minimum BOOST_THREAD_VERSION=3 if C++11 is on?
As I said in another post the Boost community didn't accept the breaking changes. Best, Vicente PS. Niall please, could you concentrate on the PO subject.

Le 04/09/13 07:53, Gavin Lambert a écrit :
I tried submitting this via Trac but for some reason it was convinced that my bug report contained spam, while refusing to tell me what part it was objecting to, and also refusing to give me a captcha or anything to convince it otherwise.
Anyways:
Bug 1: the Boost.Thread documentation and release history indicate that BOOST_THREAD_VERSION==3 is the default since v1.52. As far as I can tell this has never been true in any released version; the latest code still has ==2. (I found a thread in boost-devel that was debating consequences of making breaking changes by default, which I assume is why this change was not actually made; but the docs need correcting.) This was my intention, but this was not possible as the Boost community didn't accept the breaking changes. Please could you point me where in the documentation this misinformation is still there?
Bug 2: when writing code using the Boost.Thread "Portable Interface" for move support/emulation, it recommends using the BOOST_THREAD_DCL_MOVABLE_BEG macro to "avoid conflicts with Boost.Move". However regardless of C++11 or not or the BOOST_THREAD_VERSION it defines a template specialisation in a way that assumes that it is called only from "namespace boost". You are right. The macro must be used inside the boost namesapce. As this usage is unlikely for any code outside the boost library itself, I think this is a bug. Well, as the constraint is not on the documentation, I consider it a bug.
namespace user { template<typename T> class test { public: BOOST_THREAD_COPYABLE_AND_MOVABLE(test)
test() {} test(const test&) {} test& operator=(BOOST_COPY_ASSIGN_REF(test) o) { return *this; } test(BOOST_THREAD_RV_REF(test) o) {} test& operator=(BOOST_THREAD_RV_REF(test) o) { return *this; } }; BOOST_THREAD_DCL_MOVABLE_BEG(T) test<T> BOOST_THREAD_DCL_MOVABLE_END }
The above code will not compile. It does compile if the DCL define is moved into a "namespace boost" block, but I do not regard this as an acceptable solution.
Suggested fix is to explicitly specify the namespace in the macro, eg. replace "enable_move_utility_emulation" with "::boost::enable_move_utility_emulation".
Humm, I don't know if this is correct. In any case I didn't know that we could specialize templates this way. Could some one confirm this kind of specializations is portable? Best, Vicente

Le 07/09/13 10:00, Vicente J. Botet Escriba a écrit :
Le 04/09/13 07:53, Gavin Lambert a écrit :
I tried submitting this via Trac but for some reason it was convinced that my bug report contained spam, while refusing to tell me what part it was objecting to, and also refusing to give me a captcha or anything to convince it otherwise.
Anyways:
Bug 1: the Boost.Thread documentation and release history indicate that BOOST_THREAD_VERSION==3 is the default since v1.52. As far as I can tell this has never been true in any released version; the latest code still has ==2. (I found a thread in boost-devel that was debating consequences of making breaking changes by default, which I assume is why this change was not actually made; but the docs need correcting.) This was my intention, but this was not possible as the Boost community didn't accept the breaking changes. Please could you point me where in the documentation this misinformation is still there?
Bug 2: when writing code using the Boost.Thread "Portable Interface" for move support/emulation, it recommends using the BOOST_THREAD_DCL_MOVABLE_BEG macro to "avoid conflicts with Boost.Move". However regardless of C++11 or not or the BOOST_THREAD_VERSION it defines a template specialisation in a way that assumes that it is called only from "namespace boost". You are right. The macro must be used inside the boost namesapce. As this usage is unlikely for any code outside the boost library itself, I think this is a bug. Well, as the constraint is not on the documentation, I consider it a bug.
namespace user { template<typename T> class test { public: BOOST_THREAD_COPYABLE_AND_MOVABLE(test)
test() {} test(const test&) {} test& operator=(BOOST_COPY_ASSIGN_REF(test) o) { return *this; } test(BOOST_THREAD_RV_REF(test) o) {} test& operator=(BOOST_THREAD_RV_REF(test) o) { return *this; } }; BOOST_THREAD_DCL_MOVABLE_BEG(T) test<T> BOOST_THREAD_DCL_MOVABLE_END }
The above code will not compile. It does compile if the DCL define is moved into a "namespace boost" block, but I do not regard this as an acceptable solution.
Suggested fix is to explicitly specify the namespace in the macro, eg. replace "enable_move_utility_emulation" with "::boost::enable_move_utility_emulation".
Humm, I don't know if this is correct. In any case I didn't know that we could specialize templates this way. Could some one confirm this kind of specializations is portable?
If I do the change I get the following error: ../../../boost/thread/lock_types.hpp:500:58: erreur: global qualification of class name is invalid before ‘{’ token I suspect that you would need to make the specialization inside boost namespace. I will update the documentation. Best, Vicente

Le 07/09/13 10:11, Vicente J. Botet Escriba a écrit :
Le 07/09/13 10:00, Vicente J. Botet Escriba a écrit :
Le 04/09/13 07:53, Gavin Lambert a écrit :
I tried submitting this via Trac but for some reason it was convinced that my bug report contained spam, while refusing to tell me what part it was objecting to, and also refusing to give me a captcha or anything to convince it otherwise.
Anyways:
Bug 1: the Boost.Thread documentation and release history indicate that BOOST_THREAD_VERSION==3 is the default since v1.52. As far as I can tell this has never been true in any released version; the latest code still has ==2. (I found a thread in boost-devel that was debating consequences of making breaking changes by default, which I assume is why this change was not actually made; but the docs need correcting.) This was my intention, but this was not possible as the Boost community didn't accept the breaking changes. Please could you point me where in the documentation this misinformation is still there?
Bug 2: when writing code using the Boost.Thread "Portable Interface" for move support/emulation, it recommends using the BOOST_THREAD_DCL_MOVABLE_BEG macro to "avoid conflicts with Boost.Move". However regardless of C++11 or not or the BOOST_THREAD_VERSION it defines a template specialisation in a way that assumes that it is called only from "namespace boost". You are right. The macro must be used inside the boost namesapce. As this usage is unlikely for any code outside the boost library itself, I think this is a bug. Well, as the constraint is not on the documentation, I consider it a bug.
namespace user { template<typename T> class test { public: BOOST_THREAD_COPYABLE_AND_MOVABLE(test)
test() {} test(const test&) {} test& operator=(BOOST_COPY_ASSIGN_REF(test) o) { return *this; } test(BOOST_THREAD_RV_REF(test) o) {} test& operator=(BOOST_THREAD_RV_REF(test) o) { return *this; } }; BOOST_THREAD_DCL_MOVABLE_BEG(T) test<T> BOOST_THREAD_DCL_MOVABLE_END }
The above code will not compile. It does compile if the DCL define is moved into a "namespace boost" block, but I do not regard this as an acceptable solution.
Suggested fix is to explicitly specify the namespace in the macro, eg. replace "enable_move_utility_emulation" with "::boost::enable_move_utility_emulation".
Humm, I don't know if this is correct. In any case I didn't know that we could specialize templates this way. Could some one confirm this kind of specializations is portable?
If I do the change I get the following error:
../../../boost/thread/lock_types.hpp:500:58: erreur: global qualification of class name is invalid before ‘{’ token
I suspect that you would need to make the specialization inside boost namespace. I will update the documentation.
It seems that someone else have found the needed feature useful (see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3730.html). Best, Vicente

Hello,
I 've used Valgrind analyze an application I wrote using Boost.Bimap.
Among its output are walls of text starting with
==21563== Invalid read of size 8
==21563== at 0x457C8F:
boost::multi_index::detail::ordered_index_node_impl ::increment(boost::multi_index::detail::ordered_index_node_impl Not sure how to interpret this. Could this indicate a bug in
Multi-Index, in Bimap, or my own code? Or perhaps it is a valgrind
hiccup? Any clues as to how to investigate this further would be
appreciated.
VK

Not sure how to interpret this. Could this indicate a bug in Multi-Index, in Bimap, or my own code? Or perhaps it is a valgrind hiccup? Any clues as to how to investigate this further would be appreciated.
Try turning on iterator debugging. I'd almost be certain it's an iterator incremented or decremented too far. libstdc++ and Dinkumware STLs both have extensive iterator debugging facilities, libc++ seems to have some support according to Google. Niall -- Currently unemployed and looking for work. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/

On 8 September 2013 21:55, Niall Douglas wrote:
Not sure how to interpret this. Could this indicate a bug in Multi-Index, in Bimap, or my own code? Or perhaps it is a valgrind hiccup? Any clues as to how to investigate this further would be appreciated.
Try turning on iterator debugging. I'd almost be certain it's an iterator incremented or decremented too far. libstdc++ and Dinkumware STLs both have extensive iterator debugging facilities, libc++ seems to have some support according to Google.
They can only debug iterators defined by the standard library, not ones defined by Boost.MultiIndex.

On Sun, Sep 8, 2013 at 11:20 PM, Jonathan Wakely
On 8 September 2013 21:55, Niall Douglas wrote:
Not sure how to interpret this. Could this indicate a bug in Multi-Index, in Bimap, or my own code? Or perhaps it is a valgrind hiccup? Any clues as to how to investigate this further would be appreciated.
Try turning on iterator debugging. I'd almost be certain it's an iterator incremented or decremented too far. libstdc++ and Dinkumware STLs both have extensive iterator debugging facilities, libc++ seems to have some support according to Google.
They can only debug iterators defined by the standard library, not ones defined by Boost.MultiIndex.
You could try BOOST_MULTI_INDEX_ENABLE_SAFE_MODE from http://www.boost.org/doc/libs/1_39_0/libs/multi_index/doc/tutorial/debug.htm... . There's a heavy runtime cost, but it did find us bugs where we updated an index field w/o telling BMI about it. Just a thought. --DD

On 8 Sep 2013 at 22:20, Jonathan Wakely wrote:
Try turning on iterator debugging. I'd almost be certain it's an iterator incremented or decremented too far. libstdc++ and Dinkumware STLs both have extensive iterator debugging facilities, libc++ seems to have some support according to Google.
They can only debug iterators defined by the standard library, not ones defined by Boost.MultiIndex.
You're absolutely right - I had it in my head that Multi Index rebound normal STL containers into a single container, but that is very wrong. My mistake. Niall -- Currently unemployed and looking for work. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/

Thank you all for your responses. I pinpointed the issue to erasing elements from the Bimap in a loop; presumably my iterator was being invalidated. I 'm now using the return value from the Bimap's erase and the issue is gone. Albert

On 7/09/2013 20:00, Quoth Vicente J. Botet Escriba:
Bug 1: the Boost.Thread documentation and release history indicate that BOOST_THREAD_VERSION==3 is the default since v1.52. [...] Please could you point me where in the documentation this misinformation is still there?
As noted, in the release history. http://www.boost.org/doc/libs/1_54_0/doc/html/thread/changes.html See the "boost 1.52" and "boost 1.51" subheadings.
Suggested fix is to explicitly specify the namespace in the macro, eg. replace "enable_move_utility_emulation" with "::boost::enable_move_utility_emulation".
Humm, I don't know if this is correct. In any case I didn't know that we could specialize templates this way. Could some one confirm this kind of specializations is portable?
It works fine for me in VC9, but as you've discovered it's apparently not valid in GCC. So I guess this is non-portable and we'll just have to live with the escape into the boost namespace. (I still don't like it though, but I realise your hands are tied.) Although, have you tried it without the initial "::"? That seems to be what GCC is actually objecting to, and theoretically the construct should still work without that as long as nobody defines some other boost subnamespace to introduce ambiguity (which would be silly anyway). Though the proposal you found suggests that this may not be universally valid either.
participants (6)
-
Dominique Devienne
-
Gavin Lambert
-
Jonathan Wakely
-
Niall Douglas
-
Vee Kay
-
Vicente J. Botet Escriba