Re: [boost] BOOST_ASSERT and __assume on MSVC

In-Reply-To: <dg7jf6$uf6$1@sea.gmane.org> kalita@poczta.onet.pl (Marcin Kalicinski) wrote (abridged):
Have you considered modifying BOOST_ASSERT to use __assume on MSVC?
It looks to me as though this risks changing the semantics of BOOST_ASSERT in a way which might break existing code. As I read the documentation, currently code like: if (!p) { BOOST_ASSERT( false ); return; } is supported and meaningful. If BOOST_DISABLE_ASSERTS is true, the macro does nothing and the return statement is executed when p is 0. If we change the macro to instead expand to __assume, then the compiler will probably omit both return and the check against zero. The documented behaviour of the code will change. Although I sympathise with the view that a failed assert should be considered undefined behaviour, I personally find the current documented behaviour quite useful. I sometimes use assert as a convenient way of saying, "issue a warning message, but only in debug builds." If we use __assume, we need to clearly distinguish between the old and the new behaviours, at the point of assert. Specifically, I suggest we add a new macro, eg named BOOST_ASSUME(x), which expands to BOOST_ASSERT(x) by default and to __assume(x) when BOOST_DISABLE_ASSERTS is true. This latter case would be documented as causing undefined behaviour if x is false. Programmers can than change their code from BOOST_ASSERT to BOOST_ASSUME at their leisure. If they believe in defensive programming, they may leave some code as BOOST_ASSERT.
Microsoft docs for __assume are here: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng /htm/msmod_36.asp
-- Dave Harris, Nottingham, UK.

Have you considered modifying BOOST_ASSERT to use __assume on MSVC? (...) Microsoft docs for __assume are here: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm...
"Dave Harris" <brangdon@cix.compulink.co.uk> wrote
(...) I suggest we add a new macro, eg named BOOST_ASSUME(x), which expands to BOOST_ASSERT(x) by default and to __assume(x) when BOOST_DISABLE_ASSERTS is true. This latter case would be documented as causing undefined behaviour if x is false.
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 think we should rather base on NDEBUG macro, the same that determines the behavior of assert. The whole change then boils down to adding these 6 lines at the end of assert.hpp: #include <boost/config.hpp> #if defined(BOOST_MSVC) && defined(NDEBUG) # define BOOST_ASSUME(e) { BOOST_ASSERT(e); if (e); else __assume(0); } #else # define BOOST_ASSUME(e) BOOST_ASSERT(e) #endif Please let me know what you think. There's also a question what should BOOST_ENABLE_ASSERT_HANDLER do with BOOST_ASSUME? Should it invoke the handler if condition is false? I would say yes, and the above code will do just that. Marcin

From: "Marcin Kalicinski" <kalita@poczta.onet.pl>
I think we should rather base on NDEBUG macro, the same that determines the behavior of assert. The whole change then boils down to adding these 6 lines at the end of assert.hpp:
#include <boost/config.hpp> #if defined(BOOST_MSVC) && defined(NDEBUG) # define BOOST_ASSUME(e) { BOOST_ASSERT(e); if (e); else __assume(0); }
Interesting. I'd have thought that calling __assume(0) was useless, but it tells the optimizer that the else clause won't occur. I wonder if that will work at all or as well as BOOST_ASSERT(e); __assume(e);. There's a real problem with your solution, however: you evaluate the expression twice. Won't the simpler, more direct form work? -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

On 9/19/05, Rob Stewart <stewart@sig.com> wrote:
From: "Marcin Kalicinski" <kalita@poczta.onet.pl>
I think we should rather base on NDEBUG macro, the same that determines the behavior of assert. The whole change then boils down to adding these 6 lines at the end of assert.hpp:
#include <boost/config.hpp> #if defined(BOOST_MSVC) && defined(NDEBUG) # define BOOST_ASSUME(e) { BOOST_ASSERT(e); if (e); else __assume(0); }
Interesting. I'd have thought that calling __assume(0) was useless, but it tells the optimizer that the else clause won't occur. I wonder if that will work at all or as well as BOOST_ASSERT(e); __assume(e);.
I think it works exactly(seeing documentation and some tests) What a __assume(0) means that the assertion is always false, which means that that place cant be executed... I think __assume should replace assert exactly as is.
There's a real problem with your solution, however: you evaluate the expression twice. Won't the simpler, more direct form work?
-- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer; _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- Felipe Magno de Almeida Developer from synergy and Computer Science student from State University of Campinas(UNICAMP). Unicamp: http://www.ic.unicamp.br Synergy: http://www.synergy.com.br "There is no dark side of the moon really. Matter of fact it's all dark."

#include <boost/config.hpp> #if defined(BOOST_MSVC) && defined(NDEBUG) # define BOOST_ASSUME(e) { BOOST_ASSERT(e); if (e); else __assume(0); }
There's a real problem with your solution, however: you evaluate the expression twice. Won't the simpler, more direct form work?
Of course, that was a silly mistake. It should be: #include <boost/config.hpp> #undef BOOST_ASSUME #if defined(BOOST_MSVC) && defined(NDEBUG) # define BOOST_ASSUME(e) { BOOST_ASSERT(e); __assume(e); } #else # define BOOST_ASSUME(e) BOOST_ASSERT(e) #endif I hope that is fine now.
Interesting. I'd have thought that calling __assume(0) was useless, but it tells the optimizer that the else clause won't occur. I wonder if that will work at all or as well as BOOST_ASSERT(e); __assume(e);
It's not useless, see my previous posts in the thread for examples of code generated with and without __assume(0). cheers, Marcin

From: "Marcin Kalicinski" <kalita@poczta.onet.pl>
Interesting. I'd have thought that calling __assume(0) was useless, but it tells the optimizer that the else clause won't occur. I wonder if that will work at all or as well as BOOST_ASSERT(e); __assume(e);
It's not useless, see my previous posts in the thread for examples of code generated with and without __assume(0).
I said "I would have thought [it] was useless." However, I consulted the documentation and found that it was useful. That's why I said it was "interesting." -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;
participants (4)
-
brangdon@cix.compulink.co.uk
-
Felipe Magno de Almeida
-
Marcin Kalicinski
-
Rob Stewart