Re: [boost] BOOST_ASSERT and __assume on MSVC

In-Reply-To: <dgmfeo$q1v$1@sea.gmane.org> kalita@poczta.onet.pl (Marcin Kalicinski) wrote (abridged):
I think generally this is a good idea, but it has a small problem. I would expect that BOOST_ASSUME should turn into __assume when compiled in "release" mode of MSVC. As of above proposed solution this is not the case - user additionally needs to define BOOST_DISABLE_ASSERTS to get __assume. So when NDEBUG is defined and BOOST_DISABLE_ASSERTS is not (I think this is 99% of cases, because few people actually use BOOST_DISABLE_ASSERTS), BOOST_ASSUME will expand to BOOST_ASSERT and the whole thing will be useless.
I did not use NDEBUG because BOOST_ASSERT doesn't, and I didn't want to revisit that decision. I imagine the policy is to use fine-grained flags and then add: #ifdef NDEBUG #define BOOST_DISABLE_ASSERTS #endif in a user-editable header somewhere. Arguably there should be a BOOST_DISABLE_ASSUMES, too, but for now I'll use BOOST_DISABLE_ASSERTS.
# define BOOST_ASSUME(e) { BOOST_ASSERT(e); if (e); else __assume(0); }
That evaluates e twice, and if e is false it is not clear whether the assert will actually do anything because it could be optimised away. I think: # define BOOST_ASSUME(e) __assume(e) is simpler and better.
There's also a question what should BOOST_ENABLE_ASSERT_HANDLER do with BOOST_ASSUME? Should it invoke the handler if condition is false?
Only if BOOST_DISABLE_ASSERTS is not defined. So the full code would be: #include <boost/config.hpp> #if defined(BOOST_MSVC) && defined(BOOST_DISABLE_ASSERTS) # define BOOST_ASSUME(e) __assume(e) #else # define BOOST_ASSUME(e) BOOST_ASSERT(e) #endif -- Dave Harris, Nottingham, UK.

Dave Harris wrote:
I did not use NDEBUG because BOOST_ASSERT doesn't, and I didn't want to revisit that decision. I imagine the policy is to use fine-grained flags and then add:
#ifdef NDEBUG #define BOOST_DISABLE_ASSERTS #endif
in a user-editable header somewhere.
The default behavior of BOOST_ASSERT is to expand to 'assert'. This means that it obeys NDEBUG, as usual. BOOST_DISABLE_ASSERTS is for situations where the user needs to disable all BOOST_ASSERTs (no assertions from within Boost are desirable) but all plain 'assert's are to be left alone.

From: brangdon@cix.compulink.co.uk (Dave Harris)
In-Reply-To: <dgmfeo$q1v$1@sea.gmane.org> kalita@poczta.onet.pl (Marcin Kalicinski) wrote (abridged):
#include <boost/config.hpp> #if defined(BOOST_MSVC) && defined(BOOST_DISABLE_ASSERTS) # define BOOST_ASSUME(e) __assume(e) #else # define BOOST_ASSUME(e) BOOST_ASSERT(e) #endif
That misses what BOOST_ASSUME should do when BOOST_DISABLE_ASSERTS is not defined. With BOOST_ASSERT enabled, BOOST_ASSUME should call both BOOST_ASSERT and __assume(): #include <boost/config.hpp> #if defined(BOOST_MSVC) # if defined(BOOST_DISABLE_ASSERTS) # define BOOST_ASSUME(e) __assume(e) # else # define BOOST_ASSUME(e) BOOST_ASSERT(e); __assume(e) # endif #else # define BOOST_ASSUME(e) BOOST_ASSERT(e) #endif (I haven't determined whether the definitions will work in all intended contexts; this can be considered conceptual.) -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

I think BOOST_ASSUME is a good idea. But there must be some warning in code that says "this might change program behaviour". I have come across code where the asserts are written and can never be tested because the condition is usually complex and depends on the state and run time behaviour of the system. The good thing about asserts at run time is that they do not prevent the code from working (in case the assert is written incorrectly and never tested) -- in a complex function you might never see a particular condition occur. For example in a complex concurrent system, if the condition occurs at run time in a non debug build (due to let say some timing issue) and the assert was badly written, assert() would work ok, but __assume() would change the behaviour of code. Basically what I am saying is that BOOST_ASSUME() would behave differently on MSVC and non MSVC platforms. In one case it would not change anything on the other (MSVC) it would make the condition true. This could lead to debugging issues and must be documented. Balbir On 9/22/05, Rob Stewart <stewart@sig.com> wrote:
#include <boost/config.hpp> #if defined(BOOST_MSVC) && defined(BOOST_DISABLE_ASSERTS) # define BOOST_ASSUME(e) __assume(e) #else # define BOOST_ASSUME(e) BOOST_ASSERT(e) #endif
That misses what BOOST_ASSUME should do when BOOST_DISABLE_ASSERTS is not defined. With BOOST_ASSERT enabled, BOOST_ASSUME should call both BOOST_ASSERT and __assume():
#include <boost/config.hpp> #if defined(BOOST_MSVC) # if defined(BOOST_DISABLE_ASSERTS) # define BOOST_ASSUME(e) __assume(e) # else # define BOOST_ASSUME(e) BOOST_ASSERT(e); __assume(e) # endif #else # define BOOST_ASSUME(e) BOOST_ASSERT(e) #endif
participants (4)
-
Balbir Singh
-
brangdon@cix.compulink.co.uk
-
Peter Dimov
-
Rob Stewart