-fno-exceptions documentation

Howard Hinnant hhinnant@apple.com
Tue Dec 6 00:45:00 GMT 2005


On Dec 5, 2005, at 5:02 PM, Paolo Carlini wrote:

> Hi Howard,
>
>> I'm trying to round up all of our documentation on -fno-exceptions.
>> I've found:
>>
>> http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen- 
>> Options
>>
>> but was wondering if there was anything more.  I'm especially
>> interested in any documentation concerning how libstdc++ reacts to
>> this compiler flag.
>
> In my opinion, there is room for improvement in the reaction itself. I
> don't know if you found out yourself this thread:
>
>     http://gcc.gnu.org/ml/gcc/2004-10/msg00099.html
>
> What do you think?
>
> Paolo.

Thanks for the pointer Paolo, I hadn't seen this one.

Options for the customer are a double-edged sword.  Customers want  
and need options.  But offering them is a support nightmare and also  
means that some options, to truly work correctly, are more of a pain  
than others for customers to correctly turn on/off.

A brief review of libstdc++ seems to indicate that we are set up to  
handle -fno-exceptions by calling abort or terminate if an  
exceptional condition is generated while in the -fno-exceptions  
mode.  This includes operator new, but requires a recompile of libstdc 
++ to get the behavior.  I.e. -fno-exceptions changes the behavior of  
the compiled binary libstdc++.  This isn't surprising, and indeed it  
is what I would expect.

So for  http://gcc.gnu.org/ml/gcc/2004-10/msg00099.html, my knee-jerk  
reaction is to say "recompile libstdc++" with that setting if you  
need it to not thrown an exception".  That being said, my response is  
probably not what the customer wanted either.  He wanted op new to  
return 0 on failure, not abort.  In general it would be nice to give  
the customer the ability to customize error handling when exceptions  
are turned off.  For example instead of calling abort() in an  
exceptional situation we might instead call a weak-linked  
__gcc_handle_error(const char* msg).  The customer then might  
override this function, inspect the message, and do something that  
makes sense for them.  The default implementation could just call  
abort(), maybe after printing out the msg.  This still requires a  
recompile of libstdc++, but at least it gives the customer another  
option.  Here's how it might look:

operator new (std::size_t sz) throw (std::bad_alloc)
{
  ...
       if (! handler)
#ifdef __EXCEPTIONS
	throw bad_alloc();
#else
         std::__gcc_handle_error("bad_alloc");
#endif
    ...
}

Hmm... this is off the cuff, but maybe __gcc_handle_error is  
templated on the return type so that it could return a value if the  
customer wanted:

operator new (std::size_t sz) throw (std::bad_alloc)
{
  ...
       if (! handler)
#ifdef __EXCEPTIONS
	throw bad_alloc();
#else
         return std::__gcc_handle_error<void*>("bad_alloc");
#endif
    ...
}

Then perhaps the customer could override on just this return type,  
inspect the msg, and if it said "bad_alloc", return NULL.  I haven't  
prototyped this so there could easily be problems I'm missing.

<aside>
Also if we want to be serious about this, the exceptions spec should  
come off when __EXCEPTIONS is defined.

operator new (std::size_t sz)
#ifdef __EXCEPTIONS
  throw (std::bad_alloc)
#endif
{
  ...
       if (! handler)
#ifdef __EXCEPTIONS
	throw bad_alloc();
#else
         return std::__gcc_handle_error<void*>("bad_alloc");
#endif
    ...
}
</aside>

Having flags that can crash the customer's app when not set  
consistently between the libstdc++ and the applications are a pita.   
There are a few ways to deal with this situation.

1.  Don't offer such options.  This is best from a support and  
reliability standpoint, but obviously it reduces customer options.
2.  Offer them, and depend on the customer to know when he needs to  
recompile libstdc++ (this appears to be where we stand today).
3.  Offer them, and offer an extension function which detects  
incompatible settings between the app and the libstdc++.  Maybe  
something like:

check(ext::__gcc_settings());

This would detect settings as compiled, and then compare them against  
a record compiled into the libstdc++, asserting with a helpful  
message if an inconsistency is found.  It should only check those  
settings which are known to cause incompatibilities between the app  
and libstdc++.  And it should never be called by us.  Customers  
should have the freedom not to have this check done if that's what  
works for them.

Just my .02.

-Howard



More information about the Libstdc++ mailing list