Boost logo

Boost :

From: John Torjo (john_at_[hidden])
Date: 2003-05-23 01:16:07


Hi Pavel,

> Hello John,
>
> > > 1. #include <stdlib.h> may be replaced with #include <cstdlib>
> > >
> > > However Dimkunware C++ library for MSVC 6 does put <cstdlib> functions
> > into
> > > std:: namespace, so
> >
> > Unfortunately, it's not true (at least not for my MSVC6 ;-))
> >
> My typo. It should be DOESN'T.
>
> #include <cstdlib>
> using std::abort;
>
> abort()
>
> should be both portable and 'right' the C++ people as well.
>

Aaa!
But I was afraid of something and ideed it happens.
I tried compiling on VC6
#include <cstdlib>
using std::abort;

- and I get a compile-time error:
'abort' is not a member of std.

>
> > >
> > > 4. the catch(...) may (under Windows) eat some system exceptions which
> > > should pass. It should generally be used only at top level of
> application.
> > >
> > I assume you're talking about Assert's destructor.
> >
> Yes. Actually here you are right and catch(...) must be here.
>
> I do not have it at hand but saw somewhere that if Win32 system exception
is
> thrown it is caught by catch(...) and the throw either doesn't propagate
> anything or the context is destroyed. I am not absolutely sure how it is.

You are totally right. But I think it's better to be on the safe side.

>
> > > Anyway, I will provide a function that will do just that (use
> > OutputDebugString).
> >
> Will it be possible to chain outputs: like log file + OutputDebugString()?

In your logger , of course.
I can actually provide a helper functor that does just that.
As a matter of fact, I will provide it.

>
> > > 7. Is it possible to write into log info from applications directly?
> (good
> > > e.g. to compare timestamps later when assert happens)
> >
> > I'm not sure I understood this, but I guess not.
> > Please provide me with an example.
> >
> Example:
>
> write_to_log("huge file copying started at %s", now());
> try {
> copy_huge_file();
> } catch(...) {
> assert(false).message("huge file copy failed, compare current timestamp
> with start timestamp to guess whare did it fail: beginning or in the
> middle");
> }
>
> Such a info is useful for control and non-interactive systems.

Aaaaaaa!
Of course, use the .msg() function. Like this:
    SMART_ASSERT(false).msg("huge file copy failed, compare current
timestamp
 with start timestamp to guess whare did it fail: beginning or in the
 middle");

This will compile and run as expected.

>
> > > 9. (I am starting to fantasize now) Would it be possible to define
some
> > > global callback to write some data into log when assert happens? Could
> > there
> > > be 'stack' of these callbacks?
> >
> > ;-)))
> >
> > But this is what the logger is for ;-)
> > The logger loggs ALL assertions.
> > Your logger can be implemented as a functor. For instance, an object, in
> > which you can add/remove streams. When a message is written to the
logger,
> > the logger can then (in our example) write the context to all its
streams.
> >
> > Or did I not understand what you meant?
> >
> It is what I mean.

Great!

>
> > > what if I want to send assert to some remote machine in distributed
> > system,
> > > is there a chance to overtake the assert output completely _and_ send
it
> > > somewhere with TIMEOUT PROTECTION?
> >
> > Sorry, but I don't understand what you meant.
> > But I guess it's possible ;-))))
> >
> I went too wild. Will it be possible to intercept assert output and call
> user code? If so anyone may implement what he wants.

Of course. Basically, there is no such thing as "assert output". There is an
'assert_context', however.
You have two things:
- a logger
- a handler.

The logger does what it wants with assert_context, but it *should* log it
somewhere.
The handler does what it wants with assert_context, but it *should* handle
it - do something appropriate to its level.

So, in your handler, you can "intercept" every assert of a given level
(example: lvl_debug), and do whatever you want.
In other words, it is possible to have your custom code to do as you wish
(and reasonable defaults are provided).

>
> > > 4. Note to naming:
> > >
> > > Maybe BOOST_SMART_ASSERT and BOOST_SMART_VERIFY should be used by
> default
> > > and users can redefine them as they need.
> >
> > True. However, someone suggested that since the library could (<crazy
mode
> > on>) make it into STL, use SMART_ASSERT/SMART_VERIFY (<crazy mode off>).
> >
> In this case STL may rename it itself. It is Boost guideline to prefix all
> macros with BOOST_. I think v_ can be exceptions but maybe some people
will
> ask not to define it by default. Macro naming is quite easy nitpick ;-)

About STL: indeed. So, what do others think? Should I call the macros
BOOST_ASSERT, BOOST_VERIFY?

About the v_ macro: I think it's ok to have it by default (but that's just
me;-)). In case it conflicts with something, a compile error will occur, and
should point the user to the problematic code. Will see the following:

#ifndef BOOST_SMART_ASSERT_DISABLE_V_
    #define v_(x) boost::smart_assert::Private::log_me((x), #x,
boost_private_assert_keeper).m_val
#endif

So, it will just #define it, and problem gone.

>
> > > Maybe if it is not possible to do 'normal' assert activity some
> emergency
> > > printout to console and abort() should be done - something really
really
> > > basic and crashproof as fallback
> >
> > I have to think about that. But I guess it would complicate things a
lot.
> >
> try {
> normal assert ...
> } catch(...) {
> try {
> fprintf(stderr, "fucked up\n");
> } catch(...) {
> }
> }
>
> ?

Aaaa!
It is a possibility. I think I will do it.
>
>
> > > 3. would it be possible somehow to say: allocate enought memory for
> assert
> > > internal structures beforehand so std::bad_alloc cannot happen during
> > > asserts?
> >
> > I was thinking about that myself.
> > But I wanted to do it for the second version. What do you all think?
> >
> I am absolutely sure Boost people will come with this (they did when name
> demangling library was discussed). If it can be compile/runtime policy it
> would be ideal.

You're probably right

Luckily, there are allocators ;-). And I will use them.
And people say the're useless ;-)

>
>
> > > 4. could there be a callback function to be called before and function
> to
> > be
> > > called after assert? E.g. I may want to pause and resume all other
> threads
> > > before/after assert. I think something with templates may have zero
> > > overhead. It may also find use in application with many processes
(take
> > > snapshot or so).
> >
> > Well, I guess so.
> > But I think you could do this within your own (custom) assert handler.
> > Are thinking of something global (unlike the assert handlers, an assert
> > handler being related to a level)?
> >
> Yes, something 'global'. Maybe it is possible within current structure - I
> didn't grok enough it to know.

I have to think about it. Anyway, it should not be too hard to do it...

>
> > > 5. thought: what about calling assert() (the _original_ one from
> assert.h)
> > > instead of abort() when it is abailable (no NDEBUG)? You may get
> platform
> > > specific UI and behavior. When assert() is not present, then fall back
> to
> > > abort().
> >
> > I don't know how useful would that be.
> > For instance, for Win32, the platform specifiy UI and behavior is within
> > abort() itself. I'm not sure it would be necessary.
> >
> Actually now I think it is nonsense - BC++B assert calls abort() without
any
> notification (that's why I wrote my one once).
>

Thanks for your comments.

Best,
John


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk