POV-Ray : Newsgroups : povray.off-topic : Standard libraries Server Time
10 Oct 2024 01:11:49 EDT (-0400)
  Standard libraries (Message 91 to 100 of 108)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 8 Messages >>>
From: Darren New
Subject: Re: Standard libraries
Date: 8 Mar 2009 19:06:09
Message: <49b44f61$1@news.povray.org>
Nicolas Alvarez wrote:
> Darren New wrote:
>> Nicolas Alvarez wrote:
>>> Darren New wrote:
>>>> I wasn't aware C++ even defined tracebacks on exceptions.
>>> It doesn't.
>> Then the traceback in your exceptions can't tell you the values, can it?
> 
> Exceptions have no "traceback" directly visible at runtime from inside the
> code.

That's what I was saying.

> You can use platform-specific code in an exception handler to get a
> stack trace (by following stack pointers).

And that's what I asked - what would I google on to see this, given it's not 
defined in exception.h?  What's it called?

> When an application crashes, the crash handler *attaches* a debugger to the
> just-segfaulted app, loads the debugging symbols from a different file,
> gets a stacktrace, and lets the crashed app die and R.I.P.

Of course, it helps that it's crashing, instead of trying to actually do 
something about the problem, I suppose.  And that most systems will have a 
debugger installed already.

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: Standard libraries
Date: 8 Mar 2009 19:20:41
Message: <49b452c9@news.povray.org>
Darren New wrote:
> And that's what I asked - what would I google on to see this, given it's
> not defined in exception.h?  What's it called?

It's not directly related to exceptions, since it's a C API (not C++).

GNU libc (not libstdc++!) has C functions to get backtraces at any moment.
It's a GNU extension. You may very well call it in an exception handler.

http://www.gnu.org/software/libtool/manual/libc/Backtraces.html

The Windows API has similar functionality through the DlgHelp module,
especially the StackWalk64() and SymFromAddr() functions.


Post a reply to this message

From: Darren New
Subject: Re: Standard libraries
Date: 8 Mar 2009 19:31:53
Message: <49b45569$1@news.povray.org>
Warp wrote:
> that objects could register themselves to some centralized, non-template
> factory, using their own typeid as key, so that the factory could create
> clones of those objects at runtime, based on those typeids.)


Actually, wouldn't this be clearer to do with virtual functions or pointers 
to functions anyway? Where does typeid make things better in that scenario? 
Isn't it just as easy to do something like

class Alpha : Beta {
    ....
    virtual const char * me() { return "Alpha:Beta"; }
    ....
}

and switch on that?  That even gives you a defined value, so you can (say) 
write it into a file and read it back on the next run to reload objects that 
serialized themselves or something. Plus, you avoid the overhead of putting 
RTTI type_info on *every* class, most of which probably won't be registered 
that way?

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: Standard libraries
Date: 8 Mar 2009 19:33:48
Message: <49b455dc@news.povray.org>
Darren New wrote:
> Warp wrote:
>> that objects could register themselves to some centralized, non-template
>> factory, using their own typeid as key, so that the factory could create
>> clones of those objects at runtime, based on those typeids.)
> 
> Actually, wouldn't this be clearer to do with virtual functions or
> pointers to functions anyway? Where does typeid make things better in that
> scenario? Isn't it just as easy to do something like
> 
> class Alpha : Beta {
>     ....
>     virtual const char * me() { return "Alpha:Beta"; }
>     ....
> }
> 
> and switch on that?  That even gives you a defined value, so you can (say)
> write it into a file and read it back on the next run to reload objects
> that serialized themselves or something.

I think the most useful feature of RTTI is not typeid() to get a string, but
dynamic_cast.

void foo(Alpha* ptr) {
    Beta* beta = dynamic_cast<Beta*>(ptr);
}

If ptr is a Beta object that was (maybe implicitly) cast to a Alpha*, then
beta is now equal to ptr (except its type is Beta*, so you can use Beta
members). If ptr actually pointed to an Alpha, or a Delta (another subclass
of Alpha), then the cast will throw a std::bad_cast exception.

In other words, dynamic_cast behaves like Java typecasts. We just call it
std::bad_cast instead of java.lang.ClassCastException.


Post a reply to this message

From: Darren New
Subject: Re: Standard libraries
Date: 8 Mar 2009 19:39:43
Message: <49b4573f@news.povray.org>
Nicolas Alvarez wrote:
> GNU libc (not libstdc++!) has C functions to get backtraces at any moment.
> It's a GNU extension. You may very well call it in an exception handler.
> 
> http://www.gnu.org/software/libtool/manual/libc/Backtraces.html

It would seem that's rather not very useful in the exception handler? Or am 
I misunderstanding?  If I catch a division-by-zero in main() and I want to 
log what function that happened in, how would I do that?

I guess what I'm asking is, isn't it the case that by the time you're in the 
exception handler, the stack frames leading to the unexpected exception have 
already been cleaned up, and all the stuff that's on the stack is working 
correctly?

If I have a server, and I want to catch and log failures, in most languages 
I do something along the lines of
  main() {
    try {
      do_main_loop();
    } except Exception e {
      log("Uncaught exception", e);
    } finally {
      clean_up();
    }
  }
but by the time I get to the log() call, the stack is gone, yes? Where would 
I put the call to "backtrace" such that I'd catch the actual function that 
threw the exception?

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: Standard libraries
Date: 8 Mar 2009 19:47:21
Message: <49b45909@news.povray.org>
Darren New wrote:
> Nicolas Alvarez wrote:
>> GNU libc (not libstdc++!) has C functions to get backtraces at any
>> moment. It's a GNU extension. You may very well call it in an exception
>> handler.
>> 
>> http://www.gnu.org/software/libtool/manual/libc/Backtraces.html
> 
> It would seem that's rather not very useful in the exception handler? Or
> am I misunderstanding?  If I catch a division-by-zero in main() and I want
> to log what function that happened in, how would I do that?

Uh... Actually you're right :)

I dunno... I think you might be able to do something like this:

template<typename E>
void my_throw_exception(E& exc) {
    //do the backtrace() dance and store the results somewhere in exc
    throw exc;
}

But that's a bit cumbersome.

(PS: Division by zero doesn't throw a C++ exception)


Post a reply to this message

From: Fredrik Eriksson
Subject: Re: Standard libraries
Date: 8 Mar 2009 19:49:45
Message: <op.uqhy5foy7bxctx@e6600>
On Mon, 09 Mar 2009 00:33:32 +0100, Nicolas Alvarez  
<nic### [at] gmailcom> wrote:
>
> void foo(Alpha* ptr) {
>     Beta* beta = dynamic_cast<Beta*>(ptr);
> }
>
> If ptr is a Beta object that was (maybe implicitly) cast to a Alpha*,  
> then
> beta is now equal to ptr (except its type is Beta*, so you can use Beta
> members). If ptr actually pointed to an Alpha, or a Delta (another  
> subclass
> of Alpha), then the cast will throw a std::bad_cast exception.

No. A failed dynamic_cast of a pointer simply returns a null pointer. Only  
failed casts of a reference result in a std::bad_cast exception.


-- 
FE


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: Standard libraries
Date: 8 Mar 2009 19:56:17
Message: <49b45b20@news.povray.org>
"Fredrik Eriksson" <fe79}--at--{yahoo}--dot--{com> wrote:
> No. A failed dynamic_cast of a pointer simply returns a null pointer. Only
> failed casts of a reference result in a std::bad_cast exception.

Thanks for that. I first thought it returned null, but then I searched the
Internets and saw a try { ... } catch(std::bad_cast), so I thought I was
wrong. I didn't notice the difference was that the example I found used
references :)


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: Standard libraries
Date: 8 Mar 2009 20:00:44
Message: <49b45c2b@news.povray.org>
Nicolas Alvarez wrote:
> template<typename E>
> void my_throw_exception(E& exc) {
>     //do the backtrace() dance and store the results somewhere in exc
>     throw exc;
> }

And yes, you do need the template. The 'throw' statement uses the *static*
type of the variable. So for example:

class MyError: public std::exception {};

void my_throw_exception(std::exception& exc) {
    throw exc;
}

void foo(int test) {
    switch (test) {
    case 1:
        throw std::exception();
        break;
    case 2:
        throw MyError();
        break;
    case 3:
        my_throw_exception(std::exception());
        break;
    case 4:
        my_throw_exception(MyError()); // <- MyError gets sliced here
        break;
    }
}

int main() {
    try {
        foo(1);
    } catch(MyError& e) {
        std::cerr << "MyError thrown\n";
    } catch(std::exception& e) {
        std::cerr << "std::exception thrown\n";
    }
}

It will only print "MyError thrown" if you pass 2 to foo().


Post a reply to this message

From: Darren New
Subject: Re: Standard libraries
Date: 8 Mar 2009 20:02:36
Message: <49b45c9c$1@news.povray.org>
Nicolas Alvarez wrote:
> I think the most useful feature of RTTI is not typeid() to get a string, but
> dynamic_cast.

Yeah, but I've never seen an OO language that lacks that feature. :-) 
Singling it out as something with a special name seems odd to me. I guess 
the C++ standards authors just like making up their own names for things. It 
would be like saying "Our language supports class-based OOP *and* virtual 
functions!"

Don't things like GCC support dynamic_cast and virtual functions this even 
if you compile without the switch that enables typeid? (Or with the switch 
that turns it off? I seem to be finding conflicting info, altho I might be 
looking at different compilers.)

It seems strange, too, that it would add any overhead at all, except maybe 
one word of pointer to each class's code, to point to the type_info object. 
Don't you need vtable pointers even if "RTTI" is turned off?

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

<<< Previous 10 Messages Goto Latest 10 Messages Next 8 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.