[utility] [assert] Proposal for a new assert macro which stores the failed values ("informative assert")
I'd like some opinions about this assert implementation which I'd like to propose as an update of the old BOOST_ASSERT. Basically it stores the failed values next to the expression string, instead of just the expression string: "INFORMATIVE_ASSERT(5*5 < 2*2);" "5*5 < 2*2 | 25 | 4" "INFORMATIVE_ASSERT(std::vector<int>(10).size() == std::vector<int>(12).size());" "std::vector<int>(10).size() > std::vector<int>(12).size() | 10 | 12" Notes - If the class can't be serialized, the byte-data is logged instead. - It writes the values to the expression string in order to be compliant with any assert implementations Easy to read implementation available here: https://docs.google.com/file/d/0B69BCPzak52DcnF5dmhRRno3V2M/edit?usp=sharing Modified version of BOOST_ASSERT available here: https://docs.google.com/file/d/0B69BCPzak52DZW1oX1AtREM4eVU/edit?usp=sharing /Viktor (Reposting this as I posted it without labels one week ago)
On Wed, Jun 5, 2013 at 7:07 PM, Viktor Sehr
I'd like some opinions about this assert implementation which I'd like to propose as an update of the old BOOST_ASSERT.
Basically it stores the failed values next to the expression string, instead of just the expression string: "INFORMATIVE_ASSERT(5*5 < 2*2);" "5*5 < 2*2 | 25 | 4"
"INFORMATIVE_ASSERT(std::vector<int>(10).size() == std::vector<int>(12).size());" "std::vector<int>(10).size() > std::vector<int>(12).size() | 10 | 12"
Notes - If the class can't be serialized, the byte-data is logged instead. - It writes the values to the expression string in order to be compliant with any assert implementations
Easy to read implementation available here:
https://docs.google.com/file/d/0B69BCPzak52DcnF5dmhRRno3V2M/edit?usp=sharing
Modified version of BOOST_ASSERT available here:
https://docs.google.com/file/d/0B69BCPzak52DZW1oX1AtREM4eVU/edit?usp=sharing
I would very much prefer BOOST_ASSERT to stay as small and lightweight as possible and equivalent to the standard assert macro by default. One reason we're not using BOOST_ASSERT_MSG much is that it uses streaming expressions to format the error message, which turns out to be too heavy in some places (e.g. it prevents small functions from inlining and fragments the hot code too much). Please, make a new macro for this feature.
I would very much prefer BOOST_ASSERT to stay as small and lightweight as possible and equivalent to the standard assert macro by default. ... Please, make a new macro for this feature.
As it is now, it's only enabled if macro #BOOST_SERIALIZED_ASSERT is defined. However point taken, I will make a new version which defines two macros.
Please, make a new macro for this feature. The boost_assert_informative.hpp (http://bit.ly/11rPrqL) is not now updated where BOOST_INFORMATIVE_ASSERT and BOOST_INFORMATIVE_ASSERT_MSG are separate macros.
/Viktor
2013/6/5 Andrey Semashev
I would very much prefer BOOST_ASSERT to stay as small and lightweight as possible and equivalent to the standard assert macro by default. One reason we're not using BOOST_ASSERT_MSG much is that it uses streaming expressions to format the error message, which turns out to be too heavy in some places (e.g. it prevents small functions from inlining and fragments the hot code too much). Please, make a new macro for this feature.
Hi, I second the problem with BOOST_ASSERT_MSG. And I'm thinking it can be trivially worked around: BOOST_ASSERT_MSG could be (conditionally) defined like so: #if defined(BOOST_ASSERT_MSG_SIMPLIFIED) #define BOOST_ASSERT_MSG( expr, msg ) assert( (expr) || !msg ) #else ... #endif Does this look like a good idea? Regards, Kris
I second the problem with BOOST_ASSERT_MSG. And I'm thinking it can be
trivially worked around: BOOST_ASSERT_MSG could be (conditionally) defined like so:
#if defined(BOOST_ASSERT_MSG_SIMPLIFIED) #define BOOST_ASSERT_MSG( expr, msg ) assert( (expr) || !msg ) #else ... #endif
I might get something wrong, but why not simply #define BOOST_ASSERT_MSG( expr, msg ) assert( expr)? The point of the msg-part, to me, is to serialize variables?
2013/6/5 Andrey Semashev
I would very much prefer BOOST_ASSERT to stay as small and lightweight as possible and equivalent to the standard assert macro by default. One reason we're not using BOOST_ASSERT_MSG much is that it uses streaming expressions to format the error message, which turns out to be too heavy in some places (e.g. it prevents small functions from inlining and fragments the hot code too much). Please, make a new macro for this feature.
2013/6/5 Krzysztof Czainski <1czajnik@gmail.com>
I second the problem with BOOST_ASSERT_MSG. And I'm thinking it can be trivially worked around: BOOST_ASSERT_MSG could be (conditionally) defined like so:
#if defined(BOOST_ASSERT_MSG_SIMPLIFIED) #define BOOST_ASSERT_MSG( expr, msg ) assert( (expr) || !msg ) #else ... #endif
2013/6/7 Viktor Sehr
I might get something wrong, but why not simply #define BOOST_ASSERT_MSG( expr, msg ) assert( expr)? The point of the msg-part, to me, is to serialize variables?
I see. My motivation comes from using boost::array::operator[]: reference operator[](size_type i) { BOOST_ASSERT_MSG( i < N, "out of range" ); return elems[i]; } I experienced problems with this function, which Andrey described above. And my proposition of simplifying BOOST_ASSERT_MSG would work around this, but I didn't think of more complicated use cases. So should there be a guideline to use the BOOST_ASSERT( expr || !"msg" ) idiom instead of BOOST_ASSERT_MSG, when msg is only a string literal, or how should this problem be addressed? Cheers, Kris
My motivation comes from using boost::array::operator[]:
reference operator[](size_type i) { BOOST_ASSERT_MSG( i < N, "out of range" ); return elems[i]; }
I experienced problems with this function, which Andrey described above. And my proposition of simplifying BOOST_ASSERT_MSG would work around this, but I didn't think of more complicated use cases.
So should there be a guideline to use the BOOST_ASSERT( expr || !"msg" ) idiom instead of BOOST_ASSERT_MSG, when msg is only a string literal, or how should this problem be addressed?
You could use regular boost assert as: BOOST_ASSERT(i < N && "out of range"); as you dont serialize any variables.
On Friday 07 June 2013 12:16:49 Krzysztof Czainski wrote:
So should there be a guideline to use the BOOST_ASSERT( expr || !"msg" ) idiom instead of BOOST_ASSERT_MSG, when msg is only a string literal, or how should this problem be addressed?
IMHO, BOOST_ASSERT_MSG should be optimized, and this is possible to do while keeping the current interface. If boost::assertion::detail::assertion_failed_msg is defined to be never inlined, and the checked condition is marked so that it is unlikely to be true, then this would solve the problems I mentioned. This will probably require adding BOOST_NOINLINE and BOOST_LIKELY/BOOST_UNLIKELY macros to Boost.Config though. I can do this a bit later, if noone objects.
On Friday 07 June 2013 14:36:13 you wrote:
On Friday 07 June 2013 12:16:49 Krzysztof Czainski wrote:
So should there be a guideline to use the BOOST_ASSERT( expr || !"msg" ) idiom instead of BOOST_ASSERT_MSG, when msg is only a string literal, or how should this problem be addressed?
IMHO, BOOST_ASSERT_MSG should be optimized, and this is possible to do while keeping the current interface. If boost::assertion::detail::assertion_failed_msg is defined to be never inlined, and the checked condition is marked so that it is unlikely to be true, then this would solve the problems I mentioned. This will probably require adding BOOST_NOINLINE and BOOST_LIKELY/BOOST_UNLIKELY macros to Boost.Config though.
I can do this a bit later, if noone objects.
Done. https://svn.boost.org/trac/boost/changeset/84682 Please, report any issues you encounter with this change.
Anyway, back to "InformativeAssert", is there any interest in adding this to boost as a separate macro? Any suggestions in how I can evolve it?
AMDG On 06/06/2013 05:38 PM, Viktor Sehr wrote:
I might get something wrong, but why not simply #define BOOST_ASSERT_MSG( expr, msg ) assert( expr)? The point of the msg-part, to me, is to serialize variables?
No. msg is expected to be a string literal. In Christ, Steven Watanabe
participants (4)
-
Andrey Semashev
-
Krzysztof Czainski
-
Steven Watanabe
-
Viktor Sehr