|
Boost : |
Subject: Re: [boost] [exception] warnings on top of trunk
From: Bryce Lelbach (blelbach_at_[hidden])
Date: 2011-05-23 11:44:28
GCC documentation:
noreturn
A few standard library functions, such as abort and exit, cannot return.
GCC knows this automatically. Some programs define their own functions that
never return. You can declare them noreturn to tell the compiler this fact.
[snip]
The noreturn keyword does not affect the exceptional path when that applies:
a noreturn-marked function may still return to the caller by throwing an
exception or calling longjmp.
p.ptr_->rethrow() is not marked as noreturn, and it throws an exception, which
makes it nonsensical IMHO. It does actually exit.
Example:
#include <stdlib.h>
#include <exception>
#include <stdlib.h>
__attribute__((noreturn)) void foo1 (void);
void foo2 (void);
__attribute__((noreturn)) void foo1 (void) { foo2(); }
void foo2 (void) { }
__attribute__((noreturn)) void bar1 (void);
void bar2 (void);
__attribute__((noreturn)) void bar1 (void) { bar2(); exit(0); }
void bar2 (void) { }
__attribute__((noreturn)) void buzz1 (void);
__attribute__((noreturn)) void buzz2 (void);
__attribute__((noreturn)) void buzz1 (void) { buzz2(); }
__attribute__((noreturn)) void buzz2 (void) { }
__attribute__((noreturn)) void yack1 (void);
__attribute__((noreturn)) void yack2 (void);
__attribute__((noreturn)) void yack1 (void) { yack2(); }
__attribute__((noreturn)) void yack2 (void) { throw std::exception(); }
int main (void) {
foo1();
bar1();
buzz1();
yack1();
}
Emits:
[10:22:04]:wash_at_[hidden]:/home/wash/sandbox$ g++ -Wall -Wextra -DNDEBUG -O3 attribute_no_return.cpp -o attribute_no_return
attribute_no_return.cpp: In function âvoid buzz2()â:
attribute_no_return.cpp:20: warning: ânoreturnâ function does return
attribute_no_return.cpp: In function âvoid foo1()â:
attribute_no_return.cpp:7: warning: ânoreturnâ function does return
On GCC 4.4.4, RHEL 6.0, x86-64.
This warning is in fact valid.
> > BOOST_ATTRIBUTE_NORETURN
> > inline
> > void
> > rethrow_exception( exception_ptr const & p )
> > {
> > BOOST_ASSERT(p);
> > p.ptr_->rethrow();
> > }
p.ptr is a shared_ptr to an exception_detail::clone_base. rethrow() is a pure
virtual function. Therefore, there is no gurantee that rethrow() won't exit,
and if it does, then rethrow_exception will exit, which could be catastrophic.
Not to mention the possibilities if exceptions are disabled (not sure if
rethrow_exception is even available in that case).
rethrow_exception should call abort() after rethrow() to ensure that it doesn't
return, or attribute noreturn should be removed. It is just an optimization...
-- Bryce Lelbach aka wash boost-spirit.com px.cct.lsu.edu github.com/lll-project
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk