This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: Rest of trivial decorations
me22 wrote:
On Sat, Apr 18, 2009 at 16:47, Jan Hubicka <hubicka@ucw.cz> wrote:
OK, thanks for pointer! Does this seem fine?
Honza
[...]
+#ifndef _GLIBCXX_NOTHROW
+# ifdef __cplusplus
+# define _GLIBCXX_NOTHROW throw()
+# else
+# define _GLIBCXX_NOTHROW __attribute__((nothrow))
+# endif
+#endif
+
By my reading, those two definitions have different meanings
(http://gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/Function-Attributes.html),
since throw() can lead to terminate, whereas the latter is presumably
UB if an exception is thrown.
Since these are cases that certainly don't throw, is there a reason to
not just use __attribute__((nothrow)) always? That ought to solve any
issue with spurious try/catch additions, too...
The difference between throw() and __attribute__((nothrow)) is
detectable at compile time via the __has_nothrow_xxx built-ins,
and using the attribute rather than throw() is suboptimal (at
least with the latest mainline).
To illustrate, when compiled with gcc 4.5 the program below runs
successfully to completion. The last case, E<int>, which fails
with both gcc 4.3 as well as the latest mainline, is especially
unfortunate IMO, since it affects composite types such as pair,
tuple, and AFAICT there's no way to avoid it in general (there
is no way to detect whether an arbitrary function may throw).
#include <assert.h>
struct A { A () throw (); };
struct B { B () __attribute__ ((nothrow)); };
struct C {
C () { foo (); }
void foo () throw ();
};
struct D {
D () { bar (); }
void bar () __attribute__ ((nothrow));
};
template <class T>
struct E {
T t;
E (): t () { }
};
int main ()
{
assert (__has_nothrow_constructor (A));
assert (!__has_nothrow_constructor (B));
assert (!__has_nothrow_constructor (C));
assert (!__has_nothrow_constructor (D));
assert (!__has_nothrow_constructor (E<int>));
}
Martin