Rest of trivial decorations
Martin Sebor
sebor@roguewave.com
Sat Apr 18 23:40:00 GMT 2009
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
More information about the Libstdc++
mailing list