C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Toward partial introspection for C++

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
Steven T. Hatton
Guest





PostPosted: Tue Aug 09, 2005 2:01 pm    Post subject: Toward partial introspection for C++ Reply with quote



I often what to use the name of the function, class, and namespace from
which an exception is thrown as part of the std::exception::what() return
NTBS. My preference would be to define my exception in such a way that it
would automatically detect and include such information. For example I
would like something such as the following:

namespace exception {
/*! type_value_t a string representation of a value and its type
*/
template<typename T>
struct type_value_t {

/// @todo specialize per type

type_value_t(const T& value){}

const std::string& get_type() const
{ return "type not available."; }

const std::string& get_value() const
{ return "value not printable"; }
};

/*! type_value_t helper function to instaniate type_value_t
*/
template<typename T>
type_value_t<T> type_value(cosnt T& value)
{ return type_value_t<T>(value); }

/*! argument triplet of type, name, value strings
*/
struct argument {
argument(const std::string& type
,const std::string& name
,const std::string& value)
:m_type (type)
,m_name (name)
,m_value(value)
{}

argument(){}//for containers

const std::string& get_type () const { return m_type; }
const std::string& get_name () const { return m_name; }
const std::string& get_value() const { return m_value; }

const std::string m_type;
const std::string m_name;
const std::string m_value;
};

/*! argument_list list of actual parameters of a function call
*/
typedef std::vector<argument> argument_list;

/*! call_info describes a function call
*/
class call_info_if {

/// @todo derive implementation(s) so user only supplies message.

public:
virtual std::string& get_return_type() const = 0;
virtual std::string& get_namespace () const = 0;
virtual std::string& get_class () const = 0;
virtual std::string& get_signature () const = 0;
virtual argument_list& get_arguments () const = 0;
virtual std::string& get_message () const = 0;
};

/*! call_info describes a function call
*/
class call_exception: std::exception {
public:
call_exception(const call_info_if& caller){
m_what += "exception::call_exceptionn" // or this->get_class(), etc.
+ caller.get_return_type() + " "
+ caller.get_namespace () + "::"
+ caller.get_class () + "::"
+ caller.get_signature () + "n";
argument_list& args(caller.get_arguments());
for(size_t i = 0; i < args.size(); ++i)
m_what += " ["+args[i].name()+" = "+args[i].value()+"]n";

m_what+= caller.get_message();
}

virtual const char* what() const throw() { return m_what.c_str(); }

virtual ~call_exception() throw() {}
protected:
std::string m_what;
};
}

struct call_info: public call_info_if {
call_info(const std::string& message):m_message(message){}
/// @todo extract other data from the context
const std::string m_message;
};

struct foo{
void bar(int i) {
throw call_exception(call_info("I threw and exception!"));
}
};

The real trick here is to get the compiler to extract the information about
the class, namespace, and function call. Perhaps a context sensitive
preprocessor.
--

Back to top
Gene Bushuyev
Guest





PostPosted: Wed Aug 10, 2005 12:44 am    Post subject: Re: Toward partial introspection for C++ Reply with quote



""Steven T. Hatton"" <hattons (AT) globalsymmetry (DOT) com> wrote

Quote:
I often what to use the name of the function, class, and namespace from
which an exception is thrown as part of the std::exception::what() return
NTBS. My preference would be to define my exception in such a way that it
would automatically detect and include such information. For example I
would like something such as the following:

Are you sure you are using exceptions for the right purposes. You are trying
to defeat exception stack unwinding mechanism, which suggests me that you
need to use assert. Where exactly exception is thrown from, class and
function name, etc. is of no value for the code that catches it and performs
recovery. But if you are catching bugs in your application then assert will
do what you want, and will stop right on the spot, and you won't need to
back trace stack to find the problem.
Just a thought,

Gene

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Steven T. Hatton
Guest





PostPosted: Wed Aug 10, 2005 6:02 am    Post subject: Re: Toward partial introspection for C++ Reply with quote



Gene Bushuyev wrote:

Quote:
""Steven T. Hatton"" <hattons (AT) globalsymmetry (DOT) com> wrote in message
news:RJmdndu7n49a8mXfRVn-gQ (AT) speakeasy (DOT) net...
I often what to use the name of the function, class, and namespace from
which an exception is thrown as part of the std::exception::what() return
NTBS. My preference would be to define my exception in such a way that
it
would automatically detect and include such information. For example I
would like something such as the following:

Are you sure you are using exceptions for the right purposes. You are
trying to defeat exception stack unwinding mechanism, which suggests me
that you need to use assert. Where exactly exception is thrown from, class
and function name, etc. is of no value for the code that catches it and
performs recovery. But if you are catching bugs in your application then
assert will do what you want, and will stop right on the spot, and you
won't need to back trace stack to find the problem.
Just a thought,

Gene

The traditional use of asserts in C and C++ is not a good way to deal with
errors in many production environments. That is, they typically result in
a system crash. They do not need to, however. They can be used to throw
exceptions.

Exceptions are not necessarily errors, but they are often errors. There is
nothing in my example that would be required of every exception object.
The suggested mechanism would be made available for those cases where one
does want such information. Actually, a similar method to that which I
described can be used to significant advantage in stack unwinding. As the
stack is popped, every calling function can register its own state in a new
exception which has, as a member, the exception it caught. What I
suggested is based on what is regularly done in Java, but my example
provides more information than is easily available in the analogous Java
context. That is, unless things have changed, or I was unaware of all the
available features (both are quite possible), there is no way to
automatically capture information about the function call parameters where
an exception originated.

What I posted was really just an off the cuff example, and was not intended
to be overly precise in what a finalized design might entail. The main
objective was to show what could be done if introspective information were
available, an hint at a means of providing that information. Other than
the idea of automatically caputring call parameters, none of the ideas I
presented were, AFAIK, original.

--
STH
http://www.kdevelop.org
http://www.suse.com
http://www.mozilla.org

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Nikos Chantziaras
Guest





PostPosted: Sun Aug 14, 2005 12:42 pm    Post subject: Re: Toward partial introspection for C++ Reply with quote

Steven T. Hatton wrote:
Quote:
[...]
Exceptions are not necessarily errors, but they are often errors.

Exceptions should always be errors. If an error is critical for a given
context though, that's another question.


Quote:
As the stack is popped, every calling function can register its
own state in a new exception which has, as a member, the exception
it caught.

What don't you just record the state in the already thrown exception and
then simply re-throw it?


---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Gabriel Dos Reis
Guest





PostPosted: Sun Aug 14, 2005 6:44 pm    Post subject: Re: Toward partial introspection for C++ Reply with quote

[email]realnc (AT) hotmail (DOT) com[/email] ("Nikos Chantziaras") writes:

Quote:
Steven T. Hatton wrote:
[...]
Exceptions are not necessarily errors, but they are often errors.

Exceptions should always be errors.

"new T[n]" may throw but then it is an error.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Gene Bushuyev
Guest





PostPosted: Sun Aug 14, 2005 11:48 pm    Post subject: Re: Toward partial introspection for C++ Reply with quote

""Steven T. Hatton"" <hattons (AT) globalsymmetry (DOT) com> wrote

Quote:
Gene Bushuyev wrote:

""Steven T. Hatton"" <hattons (AT) globalsymmetry (DOT) com> wrote in message
news:RJmdndu7n49a8mXfRVn-gQ (AT) speakeasy (DOT) net...
I often what to use the name of the function, class, and namespace from
which an exception is thrown as part of the std::exception::what() return
NTBS. My preference would be to define my exception in such a way that
it
would automatically detect and include such information. For example I
would like something such as the following:

Are you sure you are using exceptions for the right purposes. You are
trying to defeat exception stack unwinding mechanism, which suggests me
that you need to use assert. Where exactly exception is thrown from, class
and function name, etc. is of no value for the code that catches it and
performs recovery. But if you are catching bugs in your application then
assert will do what you want, and will stop right on the spot, and you
won't need to back trace stack to find the problem.
Just a thought,

Gene

The traditional use of asserts in C and C++ is not a good way to deal with
errors in many production environments. That is, they typically result in
a system crash. They do not need to, however. They can be used to throw
exceptions.

The most important question you need to ask if you want to decide on error
mechanism is whether you want stack being unwound. I think your question
indicated "no." If the answer is no, then exceptions is the wrong mechanism, as
you're now coping with stack unwinding instead of taking advantage of it.
There is nothing wrong with process termination that failed assertion leads to.
Firstly, it indicates an internal implementation error and should be debugged,
the program wasn't designed and cannot recover from it. Secondly, it doesn't
mean that you cannot log and report the error the way you want it. And you don't
have to use assert() macro if you don't want to, you can choose another way to
terminate the program without stack being unwound, because that's what you want
for debugging of that program bug.
Exceptions on the other hand provide mechanism for recovery or graceful
termination. If the code is designed correctly, the catch site doesn't need to
know where exception originated and it doesn't need to know the stack trace.
It's sufficient to know that the program is still in a valid state, the
automatic objects were destroyed, and it knows what to do with the exception.

Quote:

Exceptions are not necessarily errors, but they are often errors. There is
nothing in my example that would be required of every exception object.
The suggested mechanism would be made available for those cases where one
does want such information. Actually, a similar method to that which I

I don't think there are such legitimate cases. This information is of no use for
a correct exception design, I can only think of possible use when debugging
buggy exception paths.

Quote:
described can be used to significant advantage in stack unwinding. As the
stack is popped, every calling function can register its own state in a new
exception which has, as a member, the exception it caught. What I
suggested is based on what is regularly done in Java, but my example
provides more information than is easily available in the analogous Java
context. That is, unless things have changed, or I was unaware of all the

There were lots of funny stuff I've seen written about Java designs. I'm no
expert in that language, so I wouldn't comment on whether the language is
wanting or the programmers or something else. It just doesn't translate into a
C++ requirements.

Quote:
available features (both are quite possible), there is no way to
automatically capture information about the function call parameters where
an exception originated.

What I posted was really just an off the cuff example, and was not intended
to be overly precise in what a finalized design might entail. The main
objective was to show what could be done if introspective information were
available, an hint at a means of providing that information. Other than
the idea of automatically caputring call parameters, none of the ideas I
presented were, AFAIK, original.

Now, you can with some additional typing capture the stack unwinding if you want
to. Below is an EXCEPTION_GUARD macro that can be added at the beginning of the
functions and can report stack trace. It comes with a price, so it's enabled
only in debug build.

class ExceptionGuard
{
const char* file;
const char* func;
const unsigned line;
const bool exception_in_progress;
public:
ExceptionGuard(const char* file, const char* func, unsigned line)
: file(file), func(func), line(line),
exception_in_progress(std::uncaught_exception()) {}
~ExceptionGuard() throw()
{
if(!exception_in_progress && std::uncaught_exception())
{
// log or report exception during stack unwinding
}
}
};

#ifdef _DEBUG
#define EXCEPTION_GUARD
ExceptionGuard function_exception_guard(__FILE__, __FUNCTION__, __LINE__)
#else
#define NXT_EXCEPTION_GUARD (void)0
#endif

P.S. I'm not against adding introspection to the language. I just don't see any
value of it in exception mechanism.

- gene

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
David Abrahams
Guest





PostPosted: Tue Aug 16, 2005 1:25 pm    Post subject: Re: Toward partial introspection for C++ Reply with quote

[email]realnc (AT) hotmail (DOT) com[/email] ("Nikos Chantziaras") writes:

Quote:
Steven T. Hatton wrote:
[...]
Exceptions are not necessarily errors, but they are often errors.

Exceptions should always be errors.

Exceptions can legitimately be used for things other than errors. For
example, throwing an exception is often the most efficient way to exit
a long-running performance-intensive process.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.